@@ -155,12 +155,14 @@ struct NamedRegionMap {
155
155
156
156
crate enum MissingLifetimeSpot < ' tcx > {
157
157
Generics ( & ' tcx hir:: Generics < ' tcx > ) ,
158
- HRLT { span : Span , span_type : HRLTSpanType } ,
158
+ HRLT { span : Span , span_type : ForLifetimeSpanType } ,
159
159
}
160
160
161
- crate enum HRLTSpanType {
162
- Empty ,
163
- Tail ,
161
+ crate enum ForLifetimeSpanType {
162
+ BoundEmpty ,
163
+ BoundTail ,
164
+ TypeEmpty ,
165
+ TypeTail ,
164
166
}
165
167
166
168
impl < ' tcx > Into < MissingLifetimeSpot < ' tcx > > for & ' tcx hir:: Generics < ' tcx > {
@@ -509,6 +511,21 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
509
511
let next_early_index = self . next_early_index ( ) ;
510
512
let was_in_fn_syntax = self . is_in_fn_syntax ;
511
513
self . is_in_fn_syntax = true ;
514
+ let lifetime_span: Option < Span > = c
515
+ . generic_params
516
+ . iter ( )
517
+ . filter_map ( |param| match param. kind {
518
+ GenericParamKind :: Lifetime { .. } => Some ( param. span ) ,
519
+ _ => None ,
520
+ } )
521
+ . last ( ) ;
522
+ let ( span, span_type) = if let Some ( span) = lifetime_span {
523
+ ( span. shrink_to_hi ( ) , ForLifetimeSpanType :: TypeTail )
524
+ } else {
525
+ ( ty. span . shrink_to_lo ( ) , ForLifetimeSpanType :: TypeEmpty )
526
+ } ;
527
+ self . missing_named_lifetime_spots
528
+ . push ( MissingLifetimeSpot :: HRLT { span, span_type } ) ;
512
529
let scope = Scope :: Binder {
513
530
lifetimes : c
514
531
. generic_params
@@ -531,6 +548,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
531
548
this. check_lifetime_params ( old_scope, & c. generic_params ) ;
532
549
intravisit:: walk_ty ( this, ty) ;
533
550
} ) ;
551
+ self . missing_named_lifetime_spots . pop ( ) ;
534
552
self . is_in_fn_syntax = was_in_fn_syntax;
535
553
}
536
554
hir:: TyKind :: TraitObject ( bounds, ref lifetime) => {
@@ -1873,12 +1891,23 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
1873
1891
err. span_suggestion (
1874
1892
* span,
1875
1893
& format ! (
1876
- "consider introducing a higher-ranked lifetime `{}` here" ,
1894
+ "consider making the {} lifetime-generic with a new `{}` lifetime" ,
1895
+ match span_type {
1896
+ ForLifetimeSpanType :: BoundEmpty
1897
+ | ForLifetimeSpanType :: BoundTail => "bound" ,
1898
+ ForLifetimeSpanType :: TypeEmpty
1899
+ | ForLifetimeSpanType :: TypeTail => "type" ,
1900
+ } ,
1877
1901
lifetime_ref
1878
1902
) ,
1879
1903
match span_type {
1880
- HRLTSpanType :: Empty => format ! ( "for<{}> " , lifetime_ref) ,
1881
- HRLTSpanType :: Tail => format ! ( ", {}" , lifetime_ref) ,
1904
+ ForLifetimeSpanType :: TypeEmpty
1905
+ | ForLifetimeSpanType :: BoundEmpty => {
1906
+ format ! ( "for<{}> " , lifetime_ref)
1907
+ }
1908
+ ForLifetimeSpanType :: TypeTail | ForLifetimeSpanType :: BoundTail => {
1909
+ format ! ( ", {}" , lifetime_ref)
1910
+ }
1882
1911
}
1883
1912
. to_string ( ) ,
1884
1913
Applicability :: MaybeIncorrect ,
@@ -2487,13 +2516,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
2487
2516
params. iter ( ) . cloned ( ) . filter ( |info| info. lifetime_count > 0 ) . collect ( ) ;
2488
2517
2489
2518
let elided_len = elided_params. len ( ) ;
2490
- let mut spans = vec ! [ ] ;
2491
2519
2492
2520
for ( i, info) in elided_params. into_iter ( ) . enumerate ( ) {
2493
2521
let ElisionFailureInfo { parent, index, lifetime_count : n, have_bound_regions, span } =
2494
2522
info;
2495
2523
2496
- spans . push ( span) ;
2524
+ db . span_label ( span, "" ) ;
2497
2525
let help_name = if let Some ( ident) =
2498
2526
parent. and_then ( |body| self . tcx . hir ( ) . body ( body) . params [ index] . pat . simple_ident ( ) )
2499
2527
{
@@ -2524,37 +2552,29 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
2524
2552
}
2525
2553
}
2526
2554
2527
- let help = |msg| {
2528
- if spans. is_empty ( ) {
2529
- db. help ( msg) ;
2530
- } else {
2531
- db. span_help ( spans, msg) ;
2532
- }
2533
- } ;
2534
-
2535
2555
if len == 0 {
2536
2556
db. help (
2537
2557
"this function's return type contains a borrowed value, \
2538
2558
but there is no value for it to be borrowed from",
2539
2559
) ;
2540
2560
self . suggest_lifetime ( db, span, "consider giving it a 'static lifetime" )
2541
2561
} else if elided_len == 0 {
2542
- help (
2562
+ db . help (
2543
2563
"this function's return type contains a borrowed value with \
2544
2564
an elided lifetime, but the lifetime cannot be derived from \
2545
2565
the arguments",
2546
2566
) ;
2547
2567
let msg = "consider giving it an explicit bounded or 'static lifetime" ;
2548
2568
self . suggest_lifetime ( db, span, msg)
2549
2569
} else if elided_len == 1 {
2550
- help ( & format ! (
2570
+ db . help ( & format ! (
2551
2571
"this function's return type contains a borrowed value, \
2552
2572
but the signature does not say which {} it is borrowed from",
2553
2573
m
2554
2574
) ) ;
2555
2575
true
2556
2576
} else {
2557
- help ( & format ! (
2577
+ db . help ( & format ! (
2558
2578
"this function's return type contains a borrowed value, \
2559
2579
but the signature does not say whether it is borrowed from {}",
2560
2580
m
@@ -2816,8 +2836,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
2816
2836
. contains ( & Some ( did) )
2817
2837
{
2818
2838
let ( span, span_type) = match & trait_ref. bound_generic_params {
2819
- [ ] => ( trait_ref. span . shrink_to_lo ( ) , HRLTSpanType :: Empty ) ,
2820
- [ .., bound] => ( bound. span . shrink_to_hi ( ) , HRLTSpanType :: Tail ) ,
2839
+ [ ] => ( trait_ref. span . shrink_to_lo ( ) , ForLifetimeSpanType :: BoundEmpty ) ,
2840
+ [ .., bound] => ( bound. span . shrink_to_hi ( ) , ForLifetimeSpanType :: BoundTail ) ,
2821
2841
} ;
2822
2842
self . missing_named_lifetime_spots
2823
2843
. push ( MissingLifetimeSpot :: HRLT { span, span_type } ) ;
0 commit comments