@@ -2789,6 +2789,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
2789
2789
} else if let TyKind :: CVarArgs = param. ty . kind {
2790
2790
// Don't suggest `&...` for ffi fn with varargs
2791
2791
None
2792
+ } else if let TyKind :: ImplTrait ( ..) = & param. ty . kind {
2793
+ // We handle these in the next `else if` branch.
2794
+ None
2792
2795
} else {
2793
2796
Some ( ( param. ty . span . shrink_to_lo ( ) , "&" . to_string ( ) ) )
2794
2797
}
@@ -2811,6 +2814,64 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
2811
2814
Applicability :: MaybeIncorrect ,
2812
2815
) ;
2813
2816
"...or alternatively,"
2817
+ } else if let Some ( ( kind, _span) ) =
2818
+ self . diagnostic_metadata . current_function
2819
+ && let FnKind :: Fn ( _, _, sig, _, _, _) = kind
2820
+ && let ast:: FnRetTy :: Ty ( ret_ty) = & sig. decl . output
2821
+ && !sig. decl . inputs . is_empty ( )
2822
+ && let arg_refs = sig
2823
+ . decl
2824
+ . inputs
2825
+ . iter ( )
2826
+ . filter_map ( |param| match & param. ty . kind {
2827
+ TyKind :: ImplTrait ( _, bounds) => Some ( bounds) ,
2828
+ _ => None ,
2829
+ } )
2830
+ . flat_map ( |bounds| bounds. into_iter ( ) )
2831
+ . collect :: < Vec < _ > > ( )
2832
+ && !arg_refs. is_empty ( )
2833
+ {
2834
+ // We have a situation like
2835
+ // fn g(mut x: impl Iterator<Item = &()>) -> Option<&()>
2836
+ // So we look at every ref in the trait bound. If there's any, we
2837
+ // suggest
2838
+ // fn g<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()>
2839
+ let mut lt_finder = LifetimeFinder {
2840
+ lifetime : lt. span ,
2841
+ found : None ,
2842
+ seen : vec ! [ ] ,
2843
+ } ;
2844
+ for bound in arg_refs {
2845
+ if let ast:: GenericBound :: Trait ( trait_ref, _) = bound {
2846
+ lt_finder. visit_trait_ref ( & trait_ref. trait_ref ) ;
2847
+ }
2848
+ }
2849
+ lt_finder. visit_ty ( ret_ty) ;
2850
+ let spans_suggs: Vec < _ > = lt_finder. seen . iter ( ) . filter_map ( |ty| {
2851
+ match & ty. kind {
2852
+ TyKind :: Ref ( _, mut_ty) => {
2853
+ let span = ty. span . with_hi ( mut_ty. ty . span . lo ( ) ) ;
2854
+ Some ( ( span, "&'a " . to_string ( ) ) )
2855
+ }
2856
+ _ => None
2857
+ }
2858
+ } ) . collect ( ) ;
2859
+ self . suggest_introducing_lifetime (
2860
+ err,
2861
+ None ,
2862
+ |err, higher_ranked, span, message, intro_sugg| {
2863
+ info ! ( ?span, ?message, ?intro_sugg) ;
2864
+ err. multipart_suggestion_verbose (
2865
+ message,
2866
+ std:: iter:: once ( ( span, intro_sugg) )
2867
+ . chain ( spans_suggs. iter ( ) . cloned ( ) )
2868
+ . collect ( ) ,
2869
+ Applicability :: MaybeIncorrect ,
2870
+ ) ;
2871
+ higher_ranked
2872
+ } ,
2873
+ ) ;
2874
+ "...or alternatively,"
2814
2875
} else {
2815
2876
"instead, you are more likely"
2816
2877
} ;
@@ -2820,7 +2881,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
2820
2881
&& let FnKind :: Fn ( _, _, sig, _, _, _) = kind
2821
2882
&& let ast:: FnRetTy :: Ty ( ty) = & sig. decl . output
2822
2883
{
2823
- let mut lt_finder = LifetimeFinder { lifetime : lt. span , found : None } ;
2884
+ let mut lt_finder = LifetimeFinder {
2885
+ lifetime : lt. span ,
2886
+ found : None ,
2887
+ seen : vec ! [ ] ,
2888
+ } ;
2824
2889
lt_finder. visit_ty ( & ty) ;
2825
2890
2826
2891
if let Some ( ty) = lt_finder. found {
@@ -2956,14 +3021,16 @@ pub(super) fn signal_lifetime_shadowing(sess: &Session, orig: Ident, shadower: I
2956
3021
struct LifetimeFinder < ' ast > {
2957
3022
lifetime : Span ,
2958
3023
found : Option < & ' ast Ty > ,
3024
+ seen : Vec < & ' ast Ty > ,
2959
3025
}
2960
3026
2961
3027
impl < ' ast > Visitor < ' ast > for LifetimeFinder < ' ast > {
2962
3028
fn visit_ty ( & mut self , t : & ' ast Ty ) {
2963
- if t. span . lo ( ) == self . lifetime . lo ( )
2964
- && let TyKind :: Ref ( _, mut_ty) = & t. kind
2965
- {
2966
- self . found = Some ( & mut_ty. ty ) ;
3029
+ if let TyKind :: Ref ( _, mut_ty) = & t. kind {
3030
+ self . seen . push ( t) ;
3031
+ if t. span . lo ( ) == self . lifetime . lo ( ) {
3032
+ self . found = Some ( & mut_ty. ty ) ;
3033
+ }
2967
3034
}
2968
3035
walk_ty ( self , t)
2969
3036
}
0 commit comments