@@ -2398,6 +2398,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
2398
2398
lifetime_refs. len ( ) ,
2399
2399
& lifetime_names,
2400
2400
self . tcx . sess . source_map ( ) . span_to_snippet ( span) . ok ( ) . as_ref ( ) . map ( |s| s. as_str ( ) ) ,
2401
+ & self . missing_named_lifetime_spots ,
2401
2402
) ;
2402
2403
}
2403
2404
@@ -2908,19 +2909,80 @@ fn add_missing_lifetime_specifiers_label(
2908
2909
count : usize ,
2909
2910
lifetime_names : & FxHashSet < ast:: Ident > ,
2910
2911
snippet : Option < & str > ,
2912
+ missing_named_lifetime_spots : & [ & hir:: Generics < ' _ > ] ,
2911
2913
) {
2912
2914
if count > 1 {
2913
2915
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
- ) ;
2923
2916
} 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
+ }
2925
2987
}
2926
2988
}
0 commit comments