@@ -1034,6 +1034,8 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
10341034 lifetime_names : & FxHashSet < ast:: Ident > ,
10351035 params : & [ ElisionFailureInfo ] ,
10361036 ) {
1037+ let snippet = self . tcx . sess . source_map ( ) . span_to_snippet ( span) . ok ( ) ;
1038+
10371039 err. span_label (
10381040 span,
10391041 & format ! (
@@ -1043,11 +1045,10 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
10431045 ) ,
10441046 ) ;
10451047
1046- let snippet = self . tcx . sess . source_map ( ) . span_to_snippet ( span) . ok ( ) ;
10471048 let suggest_existing = |err : & mut DiagnosticBuilder < ' _ > , sugg| {
10481049 err. span_suggestion_verbose (
10491050 span,
1050- "consider using the named lifetime" ,
1051+ & format ! ( "consider using the `{}` lifetime" , lifetime_names . iter ( ) . next ( ) . unwrap ( ) ) ,
10511052 sugg,
10521053 Applicability :: MaybeIncorrect ,
10531054 ) ;
@@ -1137,6 +1138,20 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
11371138 ( 0 , _, Some ( snippet) ) if !snippet. ends_with ( '>' ) && count == 1 => {
11381139 suggest_new ( err, & format ! ( "{}<'a>" , snippet) ) ;
11391140 }
1141+ ( n, ..) if n > 1 => {
1142+ let spans: Vec < Span > = lifetime_names. iter ( ) . map ( |lt| lt. span ) . collect ( ) ;
1143+ err. span_note ( spans, "these named lifetimes are available to use" ) ;
1144+ if Some ( "" ) == snippet. as_deref ( ) {
1145+ // This happens when we have `Foo<T>` where we point at the space before `T`,
1146+ // but this can be confusing so we give a suggestion with placeholders.
1147+ err. span_suggestion_verbose (
1148+ span,
1149+ "consider using one of the available lifetimes here" ,
1150+ "'lifetime, " . repeat ( count) ,
1151+ Applicability :: HasPlaceholders ,
1152+ ) ;
1153+ }
1154+ }
11401155 _ => { }
11411156 }
11421157 }
0 commit comments