@@ -16,6 +16,8 @@ use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder,
16
16
use rustc_hir as hir;
17
17
use rustc_hir:: def_id:: DefId ;
18
18
use rustc_hir:: intravisit:: Visitor ;
19
+ use rustc_hir:: GenericParam ;
20
+ use rustc_hir:: Item ;
19
21
use rustc_hir:: Node ;
20
22
use rustc_middle:: mir:: abstract_const:: NotConstEvaluatable ;
21
23
use rustc_middle:: ty:: error:: ExpectedFound ;
@@ -1095,6 +1097,13 @@ trait InferCtxtPrivExt<'tcx> {
1095
1097
node : Node < ' hir > ,
1096
1098
) ;
1097
1099
1100
+ fn maybe_indirection_for_unsized (
1101
+ & self ,
1102
+ err : & mut DiagnosticBuilder < ' tcx > ,
1103
+ item : & ' hir Item < ' hir > ,
1104
+ param : & ' hir GenericParam < ' hir > ,
1105
+ ) -> bool ;
1106
+
1098
1107
fn is_recursive_obligation (
1099
1108
& self ,
1100
1109
obligated_types : & mut Vec < & ty:: TyS < ' tcx > > ,
@@ -1821,38 +1830,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
1821
1830
..
1822
1831
} ,
1823
1832
) => {
1824
- // Suggesting `T: ?Sized` is only valid in an ADT if `T` is only used in a
1825
- // borrow. `struct S<'a, T: ?Sized>(&'a T);` is valid, `struct S<T: ?Sized>(T);`
1826
- // is not.
1827
- let mut visitor = FindTypeParam {
1828
- param : param. name . ident ( ) . name ,
1829
- invalid_spans : vec ! [ ] ,
1830
- nested : false ,
1831
- } ;
1832
- visitor. visit_item ( item) ;
1833
- if !visitor. invalid_spans . is_empty ( ) {
1834
- let mut multispan: MultiSpan = param. span . into ( ) ;
1835
- multispan. push_span_label (
1836
- param. span ,
1837
- format ! ( "this could be changed to `{}: ?Sized`..." , param. name. ident( ) ) ,
1838
- ) ;
1839
- for sp in visitor. invalid_spans {
1840
- multispan. push_span_label (
1841
- sp,
1842
- format ! (
1843
- "...if indirection were used here: `Box<{}>`" ,
1844
- param. name. ident( ) ,
1845
- ) ,
1846
- ) ;
1847
- }
1848
- err. span_help (
1849
- multispan,
1850
- & format ! (
1851
- "you could relax the implicit `Sized` bound on `{T}` if it were \
1852
- used through indirection like `&{T}` or `Box<{T}>`",
1853
- T = param. name. ident( ) ,
1854
- ) ,
1855
- ) ;
1833
+ if self . maybe_indirection_for_unsized ( err, item, param) {
1856
1834
return ;
1857
1835
}
1858
1836
}
@@ -1872,6 +1850,43 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
1872
1850
}
1873
1851
}
1874
1852
1853
+ fn maybe_indirection_for_unsized (
1854
+ & self ,
1855
+ err : & mut DiagnosticBuilder < ' tcx > ,
1856
+ item : & ' hir Item < ' hir > ,
1857
+ param : & ' hir GenericParam < ' hir > ,
1858
+ ) -> bool {
1859
+ // Suggesting `T: ?Sized` is only valid in an ADT if `T` is only used in a
1860
+ // borrow. `struct S<'a, T: ?Sized>(&'a T);` is valid, `struct S<T: ?Sized>(T);`
1861
+ // is not.
1862
+ let mut visitor =
1863
+ FindTypeParam { param : param. name . ident ( ) . name , invalid_spans : vec ! [ ] , nested : false } ;
1864
+ visitor. visit_item ( item) ;
1865
+ if !visitor. invalid_spans . is_empty ( ) {
1866
+ let mut multispan: MultiSpan = param. span . into ( ) ;
1867
+ multispan. push_span_label (
1868
+ param. span ,
1869
+ format ! ( "this could be changed to `{}: ?Sized`..." , param. name. ident( ) ) ,
1870
+ ) ;
1871
+ for sp in visitor. invalid_spans {
1872
+ multispan. push_span_label (
1873
+ sp,
1874
+ format ! ( "...if indirection were used here: `Box<{}>`" , param. name. ident( ) ) ,
1875
+ ) ;
1876
+ }
1877
+ err. span_help (
1878
+ multispan,
1879
+ & format ! (
1880
+ "you could relax the implicit `Sized` bound on `{T}` if it were \
1881
+ used through indirection like `&{T}` or `Box<{T}>`",
1882
+ T = param. name. ident( ) ,
1883
+ ) ,
1884
+ ) ;
1885
+ return true ;
1886
+ }
1887
+ false
1888
+ }
1889
+
1875
1890
fn is_recursive_obligation (
1876
1891
& self ,
1877
1892
obligated_types : & mut Vec < & ty:: TyS < ' tcx > > ,
0 commit comments