@@ -2398,6 +2398,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
23982398 lifetime_refs. len ( ) ,
23992399 & lifetime_names,
24002400 self . tcx . sess . source_map ( ) . span_to_snippet ( span) . ok ( ) . as_ref ( ) . map ( |s| s. as_str ( ) ) ,
2401+ & self . missing_named_lifetime_spots ,
24012402 ) ;
24022403 }
24032404
@@ -2908,19 +2909,80 @@ fn add_missing_lifetime_specifiers_label(
29082909 count : usize ,
29092910 lifetime_names : & FxHashSet < ast:: Ident > ,
29102911 snippet : Option < & str > ,
2912+ missing_named_lifetime_spots : & [ & hir:: Generics < ' _ > ] ,
29112913) {
29122914 if count > 1 {
29132915 err. span_label ( span, format ! ( "expected {} lifetime parameters" , count) ) ;
2914- } else if let ( 1 , Some ( name) , Some ( "&" ) ) =
2915- ( lifetime_names. len ( ) , lifetime_names. iter ( ) . next ( ) , snippet)
2916- {
2917- err. span_suggestion (
2918- span,
2919- "consider using the named lifetime" ,
2920- format ! ( "&{} " , name) ,
2921- Applicability :: MaybeIncorrect ,
2922- ) ;
29232916 } else {
2924- err. span_label ( span, "expected lifetime parameter" ) ;
2917+ let mut introduce_suggestion = vec ! [ ] ;
2918+ if let Some ( generics) = missing_named_lifetime_spots. iter ( ) . last ( ) {
2919+ introduce_suggestion. push ( match & generics. params {
2920+ [ ] => ( generics. span , "<'lifetime>" . to_string ( ) ) ,
2921+ [ param, ..] => ( param. span . shrink_to_lo ( ) , "'lifetime, " . to_string ( ) ) ,
2922+ } ) ;
2923+ }
2924+
2925+ match ( lifetime_names. len ( ) , lifetime_names. iter ( ) . next ( ) , snippet) {
2926+ ( 1 , Some ( name) , Some ( "&" ) ) => {
2927+ err. span_suggestion (
2928+ span,
2929+ "consider using the named lifetime" ,
2930+ format ! ( "&{} " , name) ,
2931+ Applicability :: MaybeIncorrect ,
2932+ ) ;
2933+ }
2934+ ( 1 , Some ( name) , Some ( "'_" ) ) => {
2935+ err. span_suggestion (
2936+ span,
2937+ "consider using the named lifetime" ,
2938+ name. to_string ( ) ,
2939+ Applicability :: MaybeIncorrect ,
2940+ ) ;
2941+ }
2942+ ( 1 , Some ( name) , Some ( snippet) ) if !snippet. ends_with ( ">" ) => {
2943+ err. span_suggestion (
2944+ span,
2945+ "consider using the named lifetime" ,
2946+ format ! ( "{}<{}>" , snippet, name) ,
2947+ Applicability :: MaybeIncorrect ,
2948+ ) ;
2949+ }
2950+ ( 0 , _, Some ( "&" ) ) => {
2951+ err. span_label ( span, "expected named lifetime parameter" ) ;
2952+ if !introduce_suggestion. is_empty ( ) {
2953+ introduce_suggestion. push ( ( span, "&'lifetime " . to_string ( ) ) ) ;
2954+ err. multipart_suggestion (
2955+ "consider introducing a named lifetime" ,
2956+ introduce_suggestion,
2957+ Applicability :: MaybeIncorrect ,
2958+ ) ;
2959+ }
2960+ }
2961+ ( 0 , _, Some ( "'_" ) ) => {
2962+ err. span_label ( span, "expected named lifetime parameter" ) ;
2963+ if !introduce_suggestion. is_empty ( ) {
2964+ introduce_suggestion. push ( ( span, "'lifetime" . to_string ( ) ) ) ;
2965+ err. multipart_suggestion (
2966+ "consider introducing a named lifetime" ,
2967+ introduce_suggestion,
2968+ Applicability :: MaybeIncorrect ,
2969+ ) ;
2970+ }
2971+ }
2972+ ( 0 , _, Some ( snippet) ) if !snippet. ends_with ( ">" ) => {
2973+ err. span_label ( span, "expected named lifetime parameter" ) ;
2974+ if !introduce_suggestion. is_empty ( ) {
2975+ introduce_suggestion. push ( ( span, format ! ( "{}<'lifetime>" , snippet) ) ) ;
2976+ err. multipart_suggestion (
2977+ "consider introducing a named lifetime" ,
2978+ introduce_suggestion,
2979+ Applicability :: MaybeIncorrect ,
2980+ ) ;
2981+ }
2982+ }
2983+ _ => {
2984+ err. span_label ( span, "expected lifetime parameter" ) ;
2985+ }
2986+ }
29252987 }
29262988}
0 commit comments