@@ -155,12 +155,14 @@ struct NamedRegionMap {
155155
156156crate enum MissingLifetimeSpot < ' tcx > {
157157 Generics ( & ' tcx hir:: Generics < ' tcx > ) ,
158- HRLT { span : Span , span_type : HRLTSpanType } ,
158+ HRLT { span : Span , span_type : ForLifetimeSpanType } ,
159159}
160160
161- crate enum HRLTSpanType {
162- Empty ,
163- Tail ,
161+ crate enum ForLifetimeSpanType {
162+ BoundEmpty ,
163+ BoundTail ,
164+ TypeEmpty ,
165+ TypeTail ,
164166}
165167
166168impl < ' tcx > Into < MissingLifetimeSpot < ' tcx > > for & ' tcx hir:: Generics < ' tcx > {
@@ -509,6 +511,21 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
509511 let next_early_index = self . next_early_index ( ) ;
510512 let was_in_fn_syntax = self . is_in_fn_syntax ;
511513 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 } ) ;
512529 let scope = Scope :: Binder {
513530 lifetimes : c
514531 . generic_params
@@ -531,6 +548,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
531548 this. check_lifetime_params ( old_scope, & c. generic_params ) ;
532549 intravisit:: walk_ty ( this, ty) ;
533550 } ) ;
551+ self . missing_named_lifetime_spots . pop ( ) ;
534552 self . is_in_fn_syntax = was_in_fn_syntax;
535553 }
536554 hir:: TyKind :: TraitObject ( bounds, ref lifetime) => {
@@ -1873,12 +1891,23 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
18731891 err. span_suggestion (
18741892 * span,
18751893 & 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+ } ,
18771901 lifetime_ref
18781902 ) ,
18791903 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+ }
18821911 }
18831912 . to_string ( ) ,
18841913 Applicability :: MaybeIncorrect ,
@@ -2487,13 +2516,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
24872516 params. iter ( ) . cloned ( ) . filter ( |info| info. lifetime_count > 0 ) . collect ( ) ;
24882517
24892518 let elided_len = elided_params. len ( ) ;
2490- let mut spans = vec ! [ ] ;
24912519
24922520 for ( i, info) in elided_params. into_iter ( ) . enumerate ( ) {
24932521 let ElisionFailureInfo { parent, index, lifetime_count : n, have_bound_regions, span } =
24942522 info;
24952523
2496- spans . push ( span) ;
2524+ db . span_label ( span, "" ) ;
24972525 let help_name = if let Some ( ident) =
24982526 parent. and_then ( |body| self . tcx . hir ( ) . body ( body) . params [ index] . pat . simple_ident ( ) )
24992527 {
@@ -2524,37 +2552,29 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
25242552 }
25252553 }
25262554
2527- let help = |msg| {
2528- if spans. is_empty ( ) {
2529- db. help ( msg) ;
2530- } else {
2531- db. span_help ( spans, msg) ;
2532- }
2533- } ;
2534-
25352555 if len == 0 {
25362556 db. help (
25372557 "this function's return type contains a borrowed value, \
25382558 but there is no value for it to be borrowed from",
25392559 ) ;
25402560 self . suggest_lifetime ( db, span, "consider giving it a 'static lifetime" )
25412561 } else if elided_len == 0 {
2542- help (
2562+ db . help (
25432563 "this function's return type contains a borrowed value with \
25442564 an elided lifetime, but the lifetime cannot be derived from \
25452565 the arguments",
25462566 ) ;
25472567 let msg = "consider giving it an explicit bounded or 'static lifetime" ;
25482568 self . suggest_lifetime ( db, span, msg)
25492569 } else if elided_len == 1 {
2550- help ( & format ! (
2570+ db . help ( & format ! (
25512571 "this function's return type contains a borrowed value, \
25522572 but the signature does not say which {} it is borrowed from",
25532573 m
25542574 ) ) ;
25552575 true
25562576 } else {
2557- help ( & format ! (
2577+ db . help ( & format ! (
25582578 "this function's return type contains a borrowed value, \
25592579 but the signature does not say whether it is borrowed from {}",
25602580 m
@@ -2816,8 +2836,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
28162836 . contains ( & Some ( did) )
28172837 {
28182838 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 ) ,
28212841 } ;
28222842 self . missing_named_lifetime_spots
28232843 . push ( MissingLifetimeSpot :: HRLT { span, span_type } ) ;
0 commit comments