@@ -2988,6 +2988,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
2988
2988
} else if let TyKind :: CVarArgs = param. ty . kind {
2989
2989
// Don't suggest `&...` for ffi fn with varargs
2990
2990
None
2991
+ } else if let TyKind :: ImplTrait ( ..) = & param. ty . kind {
2992
+ // We handle these in the next `else if` branch.
2993
+ None
2991
2994
} else {
2992
2995
Some ( ( param. ty . span . shrink_to_lo ( ) , "&" . to_string ( ) ) )
2993
2996
}
@@ -3010,6 +3013,64 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
3010
3013
Applicability :: MaybeIncorrect ,
3011
3014
) ;
3012
3015
"...or alternatively,"
3016
+ } else if let Some ( ( kind, _span) ) =
3017
+ self . diagnostic_metadata . current_function
3018
+ && let FnKind :: Fn ( _, _, sig, _, _, _) = kind
3019
+ && let ast:: FnRetTy :: Ty ( ret_ty) = & sig. decl . output
3020
+ && !sig. decl . inputs . is_empty ( )
3021
+ && let arg_refs = sig
3022
+ . decl
3023
+ . inputs
3024
+ . iter ( )
3025
+ . filter_map ( |param| match & param. ty . kind {
3026
+ TyKind :: ImplTrait ( _, bounds) => Some ( bounds) ,
3027
+ _ => None ,
3028
+ } )
3029
+ . flat_map ( |bounds| bounds. into_iter ( ) )
3030
+ . collect :: < Vec < _ > > ( )
3031
+ && !arg_refs. is_empty ( )
3032
+ {
3033
+ // We have a situation like
3034
+ // fn g(mut x: impl Iterator<Item = &()>) -> Option<&()>
3035
+ // So we look at every ref in the trait bound. If there's any, we
3036
+ // suggest
3037
+ // fn g<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()>
3038
+ let mut lt_finder = LifetimeFinder {
3039
+ lifetime : lt. span ,
3040
+ found : None ,
3041
+ seen : vec ! [ ] ,
3042
+ } ;
3043
+ for bound in arg_refs {
3044
+ if let ast:: GenericBound :: Trait ( trait_ref, _) = bound {
3045
+ lt_finder. visit_trait_ref ( & trait_ref. trait_ref ) ;
3046
+ }
3047
+ }
3048
+ lt_finder. visit_ty ( ret_ty) ;
3049
+ let spans_suggs: Vec < _ > = lt_finder. seen . iter ( ) . filter_map ( |ty| {
3050
+ match & ty. kind {
3051
+ TyKind :: Ref ( _, mut_ty) => {
3052
+ let span = ty. span . with_hi ( mut_ty. ty . span . lo ( ) ) ;
3053
+ Some ( ( span, "&'a " . to_string ( ) ) )
3054
+ }
3055
+ _ => None
3056
+ }
3057
+ } ) . collect ( ) ;
3058
+ self . suggest_introducing_lifetime (
3059
+ err,
3060
+ None ,
3061
+ |err, higher_ranked, span, message, intro_sugg| {
3062
+ info ! ( ?span, ?message, ?intro_sugg) ;
3063
+ err. multipart_suggestion_verbose (
3064
+ message,
3065
+ std:: iter:: once ( ( span, intro_sugg) )
3066
+ . chain ( spans_suggs. iter ( ) . cloned ( ) )
3067
+ . collect ( ) ,
3068
+ Applicability :: MaybeIncorrect ,
3069
+ ) ;
3070
+ higher_ranked
3071
+ } ,
3072
+ ) ;
3073
+ "...or alternatively,"
3013
3074
} else {
3014
3075
"instead, you are more likely"
3015
3076
} ;
@@ -3019,7 +3080,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
3019
3080
&& let FnKind :: Fn ( _, _, sig, _, _, _) = kind
3020
3081
&& let ast:: FnRetTy :: Ty ( ty) = & sig. decl . output
3021
3082
{
3022
- let mut lt_finder = LifetimeFinder { lifetime : lt. span , found : None } ;
3083
+ let mut lt_finder = LifetimeFinder {
3084
+ lifetime : lt. span ,
3085
+ found : None ,
3086
+ seen : vec ! [ ] ,
3087
+ } ;
3023
3088
lt_finder. visit_ty ( & ty) ;
3024
3089
3025
3090
if let Some ( ty) = lt_finder. found {
@@ -3155,14 +3220,16 @@ pub(super) fn signal_lifetime_shadowing(sess: &Session, orig: Ident, shadower: I
3155
3220
struct LifetimeFinder < ' ast > {
3156
3221
lifetime : Span ,
3157
3222
found : Option < & ' ast Ty > ,
3223
+ seen : Vec < & ' ast Ty > ,
3158
3224
}
3159
3225
3160
3226
impl < ' ast > Visitor < ' ast > for LifetimeFinder < ' ast > {
3161
3227
fn visit_ty ( & mut self , t : & ' ast Ty ) {
3162
- if t. span . lo ( ) == self . lifetime . lo ( )
3163
- && let TyKind :: Ref ( _, mut_ty) = & t. kind
3164
- {
3165
- self . found = Some ( & mut_ty. ty ) ;
3228
+ if let TyKind :: Ref ( _, mut_ty) = & t. kind {
3229
+ self . seen . push ( t) ;
3230
+ if t. span . lo ( ) == self . lifetime . lo ( ) {
3231
+ self . found = Some ( & mut_ty. ty ) ;
3232
+ }
3166
3233
}
3167
3234
walk_ty ( self , t)
3168
3235
}
0 commit comments