@@ -2298,6 +2298,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
2298
2298
let span = lifetime_refs[ 0 ] . span ;
2299
2299
let mut late_depth = 0 ;
2300
2300
let mut scope = self . scope ;
2301
+ let mut lifetime_names = FxHashSet :: default ( ) ;
2301
2302
let error = loop {
2302
2303
match * scope {
2303
2304
// Do not assign any resolution, it will be inferred.
@@ -2310,7 +2311,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
2310
2311
scope = s;
2311
2312
}
2312
2313
2313
- Scope :: Elision { ref elide, .. } => {
2314
+ Scope :: Elision { ref elide, ref s , .. } => {
2314
2315
let lifetime = match * elide {
2315
2316
Elide :: FreshLateAnon ( ref counter) => {
2316
2317
for lifetime_ref in lifetime_refs {
@@ -2320,7 +2321,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
2320
2321
return ;
2321
2322
}
2322
2323
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
+ }
2324
2334
} ;
2325
2335
for lifetime_ref in lifetime_refs {
2326
2336
self . insert_lifetime ( lifetime_ref, lifetime) ;
@@ -2343,7 +2353,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
2343
2353
}
2344
2354
}
2345
2355
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
+ ) ;
2347
2363
}
2348
2364
2349
2365
err. emit ( ) ;
@@ -2884,10 +2900,23 @@ fn add_missing_lifetime_specifiers_label(
2884
2900
err : & mut DiagnosticBuilder < ' _ > ,
2885
2901
span : Span ,
2886
2902
count : usize ,
2903
+ lifetime_names : & FxHashSet < ast:: Ident > ,
2904
+ snippet : Option < & str > ,
2887
2905
) {
2888
2906
if count > 1 {
2889
2907
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
+ ) ;
2890
2919
} else {
2891
2920
err. span_label ( span, "expected lifetime parameter" ) ;
2892
- } ;
2921
+ }
2893
2922
}
0 commit comments