@@ -16,6 +16,8 @@ use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder,
1616use rustc_hir as hir;
1717use rustc_hir:: def_id:: DefId ;
1818use rustc_hir:: intravisit:: Visitor ;
19+ use rustc_hir:: GenericParam ;
20+ use rustc_hir:: Item ;
1921use rustc_hir:: Node ;
2022use rustc_middle:: mir:: abstract_const:: NotConstEvaluatable ;
2123use rustc_middle:: ty:: error:: ExpectedFound ;
@@ -1095,6 +1097,13 @@ trait InferCtxtPrivExt<'tcx> {
10951097 node : Node < ' hir > ,
10961098 ) ;
10971099
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+
10981107 fn is_recursive_obligation (
10991108 & self ,
11001109 obligated_types : & mut Vec < & ty:: TyS < ' tcx > > ,
@@ -1821,38 +1830,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
18211830 ..
18221831 } ,
18231832 ) => {
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) {
18561834 return ;
18571835 }
18581836 }
@@ -1872,6 +1850,43 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
18721850 }
18731851 }
18741852
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+
18751890 fn is_recursive_obligation (
18761891 & self ,
18771892 obligated_types : & mut Vec < & ty:: TyS < ' tcx > > ,
0 commit comments