@@ -2299,19 +2299,26 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
22992299 let span = lifetime_refs[ 0 ] . span ;
23002300 let mut late_depth = 0 ;
23012301 let mut scope = self . scope ;
2302+ let mut lifetime_names = FxHashSet :: default ( ) ;
23022303 let error = loop {
23032304 match * scope {
23042305 // Do not assign any resolution, it will be inferred.
23052306 Scope :: Body { .. } => return ,
23062307
23072308 Scope :: Root => break None ,
23082309
2309- Scope :: Binder { s, .. } => {
2310+ Scope :: Binder { s, ref lifetimes, .. } => {
2311+ // collect named lifetimes for suggestions
2312+ for name in lifetimes. keys ( ) {
2313+ if let hir:: ParamName :: Plain ( name) = name {
2314+ lifetime_names. insert ( * name) ;
2315+ }
2316+ }
23102317 late_depth += 1 ;
23112318 scope = s;
23122319 }
23132320
2314- Scope :: Elision { ref elide, .. } => {
2321+ Scope :: Elision { ref elide, ref s , .. } => {
23152322 let lifetime = match * elide {
23162323 Elide :: FreshLateAnon ( ref counter) => {
23172324 for lifetime_ref in lifetime_refs {
@@ -2321,7 +2328,17 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
23212328 return ;
23222329 }
23232330 Elide :: Exact ( l) => l. shifted ( late_depth) ,
2324- Elide :: Error ( ref e) => break Some ( e) ,
2331+ Elide :: Error ( ref e) => {
2332+ if let Scope :: Binder { ref lifetimes, .. } = s {
2333+ // collect named lifetimes for suggestions
2334+ for name in lifetimes. keys ( ) {
2335+ if let hir:: ParamName :: Plain ( name) = name {
2336+ lifetime_names. insert ( * name) ;
2337+ }
2338+ }
2339+ }
2340+ break Some ( e) ;
2341+ }
23252342 } ;
23262343 for lifetime_ref in lifetime_refs {
23272344 self . insert_lifetime ( lifetime_ref, lifetime) ;
@@ -2344,7 +2361,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
23442361 }
23452362 }
23462363 if add_label {
2347- add_missing_lifetime_specifiers_label ( & mut err, span, lifetime_refs. len ( ) ) ;
2364+ add_missing_lifetime_specifiers_label (
2365+ & mut err,
2366+ span,
2367+ lifetime_refs. len ( ) ,
2368+ & lifetime_names,
2369+ self . tcx . sess . source_map ( ) . span_to_snippet ( span) . ok ( ) . as_ref ( ) . map ( |s| s. as_str ( ) ) ,
2370+ ) ;
23482371 }
23492372
23502373 err. emit ( ) ;
@@ -2885,10 +2908,23 @@ fn add_missing_lifetime_specifiers_label(
28852908 err : & mut DiagnosticBuilder < ' _ > ,
28862909 span : Span ,
28872910 count : usize ,
2911+ lifetime_names : & FxHashSet < ast:: Ident > ,
2912+ snippet : Option < & str > ,
28882913) {
28892914 if count > 1 {
28902915 err. span_label ( span, format ! ( "expected {} lifetime parameters" , count) ) ;
2916+ } else if let ( 1 , Some ( name) , Some ( "&" ) ) = (
2917+ lifetime_names. len ( ) ,
2918+ lifetime_names. iter ( ) . next ( ) ,
2919+ snippet,
2920+ ) {
2921+ err. span_suggestion (
2922+ span,
2923+ "consider using the named lifetime" ,
2924+ format ! ( "&{} " , name) ,
2925+ Applicability :: MaybeIncorrect ,
2926+ ) ;
28912927 } else {
28922928 err. span_label ( span, "expected lifetime parameter" ) ;
2893- } ;
2929+ }
28942930}
0 commit comments