@@ -2298,6 +2298,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
22982298 let span = lifetime_refs[ 0 ] . span ;
22992299 let mut late_depth = 0 ;
23002300 let mut scope = self . scope ;
2301+ let mut lifetime_names = FxHashSet :: default ( ) ;
23012302 let error = loop {
23022303 match * scope {
23032304 // Do not assign any resolution, it will be inferred.
@@ -2310,7 +2311,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
23102311 scope = s;
23112312 }
23122313
2313- Scope :: Elision { ref elide, .. } => {
2314+ Scope :: Elision { ref elide, ref s , .. } => {
23142315 let lifetime = match * elide {
23152316 Elide :: FreshLateAnon ( ref counter) => {
23162317 for lifetime_ref in lifetime_refs {
@@ -2320,7 +2321,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
23202321 return ;
23212322 }
23222323 Elide :: Exact ( l) => l. shifted ( late_depth) ,
2323- Elide :: Error ( ref e) => break Some ( e) ,
2324+ Elide :: Error ( ref e) => {
2325+ if let Scope :: Binder { ref lifetimes, .. } = s {
2326+ for name in lifetimes. keys ( ) {
2327+ if let hir:: ParamName :: Plain ( name) = name {
2328+ lifetime_names. insert ( * name) ;
2329+ }
2330+ }
2331+ }
2332+ break Some ( e) ;
2333+ }
23242334 } ;
23252335 for lifetime_ref in lifetime_refs {
23262336 self . insert_lifetime ( lifetime_ref, lifetime) ;
@@ -2343,7 +2353,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
23432353 }
23442354 }
23452355 if add_label {
2346- add_missing_lifetime_specifiers_label ( & mut err, span, lifetime_refs. len ( ) ) ;
2356+ add_missing_lifetime_specifiers_label (
2357+ & mut err,
2358+ span,
2359+ lifetime_refs. len ( ) ,
2360+ & lifetime_names,
2361+ self . tcx . sess . source_map ( ) . span_to_snippet ( span) . ok ( ) . as_ref ( ) . map ( |s| s. as_str ( ) ) ,
2362+ ) ;
23472363 }
23482364
23492365 err. emit ( ) ;
@@ -2884,10 +2900,23 @@ fn add_missing_lifetime_specifiers_label(
28842900 err : & mut DiagnosticBuilder < ' _ > ,
28852901 span : Span ,
28862902 count : usize ,
2903+ lifetime_names : & FxHashSet < ast:: Ident > ,
2904+ snippet : Option < & str > ,
28872905) {
28882906 if count > 1 {
28892907 err. span_label ( span, format ! ( "expected {} lifetime parameters" , count) ) ;
2908+ } else if let ( 1 , Some ( name) , Some ( "&" ) ) = (
2909+ lifetime_names. len ( ) ,
2910+ lifetime_names. iter ( ) . next ( ) ,
2911+ snippet,
2912+ ) {
2913+ err. span_suggestion (
2914+ span,
2915+ & format ! ( "consider using the named lifetime `{}`" , name) ,
2916+ format ! ( "&{} " , name) ,
2917+ Applicability :: MaybeIncorrect ,
2918+ ) ;
28902919 } else {
28912920 err. span_label ( span, "expected lifetime parameter" ) ;
2892- } ;
2921+ }
28932922}
0 commit comments