11use  clippy_utils:: diagnostics:: { span_lint,  span_lint_and_then} ; 
22use  clippy_utils:: trait_ref_of_method; 
33use  itertools:: Itertools ; 
4+ use  rustc_ast:: visit:: { try_visit,  walk_list} ; 
45use  rustc_data_structures:: fx:: { FxHashSet ,  FxIndexMap ,  FxIndexSet } ; 
56use  rustc_errors:: Applicability ; 
67use  rustc_hir:: FnRetTy :: Return ; 
@@ -11,8 +12,8 @@ use rustc_hir::intravisit::{
1112} ; 
1213use  rustc_hir:: { 
1314    BareFnTy ,  BodyId ,  FnDecl ,  FnSig ,  GenericArg ,  GenericArgs ,  GenericBound ,  GenericParam ,  GenericParamKind ,  Generics , 
14-     Impl ,  ImplItem ,  ImplItemKind ,  Item ,  ItemKind ,  Lifetime ,  LifetimeName ,  LifetimeParamKind ,  Node ,  PolyTraitRef , 
15-     PredicateOrigin ,  TraitFn ,  TraitItem ,  TraitItemKind ,  Ty ,  TyKind ,  WherePredicate ,  lang_items, 
15+     HirId ,   Impl ,  ImplItem ,  ImplItemKind ,  Item ,  ItemKind ,  Lifetime ,  LifetimeName ,  LifetimeParamKind ,  Node ,  PolyTraitRef , 
16+     PredicateOrigin ,  TraitFn ,  TraitItem ,  TraitItemKind ,  Ty ,  TyKind ,  WhereBoundPredicate ,   WherePredicate ,  lang_items, 
1617} ; 
1718use  rustc_lint:: { LateContext ,  LateLintPass ,  LintContext } ; 
1819use  rustc_middle:: hir:: map:: Map ; 
@@ -492,18 +493,23 @@ fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_
492493struct  Usage  { 
493494    lifetime :  Lifetime , 
494495    in_where_predicate :  bool , 
496+     in_bounded_ty :  bool , 
495497    in_generics_arg :  bool , 
496498} 
497499
498500struct  LifetimeChecker < ' cx ,  ' tcx ,  F >  { 
499501    cx :  & ' cx  LateContext < ' tcx > , 
500502    map :  FxIndexMap < LocalDefId ,  Vec < Usage > > , 
501503    where_predicate_depth :  usize , 
504+     bounded_ty_depth :  usize , 
502505    generic_args_depth :  usize , 
503506    phantom :  std:: marker:: PhantomData < F > , 
504507} 
505508
506- impl < ' cx ,  ' tcx ,  F >  LifetimeChecker < ' cx ,  ' tcx ,  F >  { 
509+ impl < ' cx ,  ' tcx ,  F >  LifetimeChecker < ' cx ,  ' tcx ,  F > 
510+ where 
511+     F :  NestedFilter < ' tcx > , 
512+ { 
507513    fn  new ( cx :  & ' cx  LateContext < ' tcx > ,  generics :  & ' tcx  Generics < ' _ > )  -> LifetimeChecker < ' cx ,  ' tcx ,  F >  { 
508514        let  map = generics
509515            . params 
@@ -519,10 +525,30 @@ impl<'cx, 'tcx, F> LifetimeChecker<'cx, 'tcx, F> {
519525            cx, 
520526            map, 
521527            where_predicate_depth :  0 , 
528+             bounded_ty_depth :  0 , 
522529            generic_args_depth :  0 , 
523530            phantom :  std:: marker:: PhantomData , 
524531        } 
525532    } 
533+ 
534+     // `visit_where_bound_predicate` is based on: 
535+     // https://github.com/rust-lang/rust/blob/864cee3ea383cc8254ba394ba355e648faa9cfa5/compiler/rustc_hir/src/intravisit.rs#L936-L939 
536+     fn  visit_where_bound_predicate ( 
537+         & mut  self , 
538+         hir_id :  HirId , 
539+         bounded_ty :  & ' tcx  Ty < ' tcx > , 
540+         bounds :  & ' tcx  [ GenericBound < ' tcx > ] , 
541+         bound_generic_params :  & ' tcx  [ GenericParam < ' tcx > ] , 
542+     )  { 
543+         try_visit ! ( self . visit_id( hir_id) ) ; 
544+ 
545+         self . bounded_ty_depth  += 1 ; 
546+         try_visit ! ( self . visit_ty( bounded_ty) ) ; 
547+         self . bounded_ty_depth  -= 1 ; 
548+ 
549+         walk_list ! ( self ,  visit_param_bound,  bounds) ; 
550+         walk_list ! ( self ,  visit_generic_param,  bound_generic_params) ; 
551+     } 
526552} 
527553
528554impl < ' tcx ,  F >  Visitor < ' tcx >  for  LifetimeChecker < ' _ ,  ' tcx ,  F > 
@@ -540,14 +566,27 @@ where
540566            usages. push ( Usage  { 
541567                lifetime :  * lifetime, 
542568                in_where_predicate :  self . where_predicate_depth  != 0 , 
569+                 in_bounded_ty :  self . bounded_ty_depth  != 0 , 
543570                in_generics_arg :  self . generic_args_depth  != 0 , 
544571            } ) ; 
545572        } 
546573    } 
547574
548575    fn  visit_where_predicate ( & mut  self ,  predicate :  & ' tcx  WherePredicate < ' tcx > )  { 
549576        self . where_predicate_depth  += 1 ; 
550-         walk_where_predicate ( self ,  predicate) ; 
577+         if  let  & WherePredicate :: BoundPredicate ( WhereBoundPredicate  { 
578+             hir_id, 
579+             bounded_ty, 
580+             bounds, 
581+             bound_generic_params, 
582+             origin :  _, 
583+             span :  _, 
584+         } )  = predicate
585+         { 
586+             self . visit_where_bound_predicate ( hir_id,  bounded_ty,  bounds,  bound_generic_params) ; 
587+         }  else  { 
588+             walk_where_predicate ( self ,  predicate) ; 
589+         } 
551590        self . where_predicate_depth  -= 1 ; 
552591    } 
553592
@@ -571,7 +610,7 @@ fn report_extra_lifetimes<'tcx>(cx: &LateContext<'tcx>, func: &'tcx FnDecl<'_>,
571610    for  ( def_id,  usages)  in  checker. map  { 
572611        if  usages
573612            . iter ( ) 
574-             . all ( |usage| usage. in_where_predicate  && !usage. in_generics_arg ) 
613+             . all ( |usage| usage. in_where_predicate  && !usage. in_bounded_ty  && !usage . in_generics_arg ) 
575614        { 
576615            span_lint ( 
577616                cx, 
@@ -598,7 +637,7 @@ fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<'
598637    for  ( & def_id,  usages)  in  & checker. map  { 
599638        if  usages
600639            . iter ( ) 
601-             . all ( |usage| usage. in_where_predicate  && !usage. in_generics_arg ) 
640+             . all ( |usage| usage. in_where_predicate  && !usage. in_bounded_ty  && !usage . in_generics_arg ) 
602641        { 
603642            span_lint ( 
604643                cx, 
@@ -614,8 +653,8 @@ fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<'
614653
615654// An `impl` lifetime is elidable if it satisfies the following conditions: 
616655// - It is used exactly once. 
617- // - That single use is not in `GenericArgs` in a `WherePredicate`. (Note that `GenericArgs` are  
618- //   different from `GenericParam`s.) 
656+ // - That single use is not in a bounded type or  `GenericArgs` in a `WherePredicate`. (Note that 
657+ //   `GenericArgs` are  different from `GenericParam`s.) 
619658fn  report_elidable_impl_lifetimes < ' tcx > ( 
620659    cx :  & LateContext < ' tcx > , 
621660    impl_ :  & ' tcx  Impl < ' _ > , 
@@ -632,6 +671,7 @@ fn report_elidable_impl_lifetimes<'tcx>(
632671                } 
633672                | Usage  { 
634673                    lifetime, 
674+                     in_bounded_ty :  false , 
635675                    in_generics_arg :  false , 
636676                    ..
637677                } , 
0 commit comments