@@ -10,13 +10,14 @@ use rustc_hir::def_id::LocalDefId;
1010use rustc_hir:: intravisit:: { InferKind , Visitor , VisitorExt , walk_ty} ;
1111use rustc_hir:: {
1212 self as hir, AmbigArg , Expr , ExprKind , FnRetTy , FnSig , GenericArgsParentheses , GenericParamKind , HirId , Impl ,
13- ImplItemImplKind , ImplItemKind , Item , ItemKind , Pat , PatExpr , PatExprKind , PatKind , Path , QPath , Ty , TyKind ,
13+ ImplItemImplKind , ImplItemKind , Item , ItemKind , Node , Pat , PatExpr , PatExprKind , PatKind , Path , QPath , Ty , TyKind ,
1414} ;
1515use rustc_lint:: { LateContext , LateLintPass } ;
1616use rustc_middle:: ty:: Ty as MiddleTy ;
1717use rustc_session:: impl_lint_pass;
1818use rustc_span:: Span ;
1919use std:: iter;
20+ use std:: ops:: ControlFlow ;
2021
2122declare_clippy_lint ! {
2223 /// ### What it does
@@ -213,6 +214,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
213214 path. res,
214215 Res :: SelfTyParam { .. } | Res :: SelfTyAlias { .. } | Res :: Def ( DefKind :: TyParam , _)
215216 )
217+ && !ty_is_in_generic_args ( cx, hir_ty)
216218 && !types_to_skip. contains ( & hir_ty. hir_id )
217219 && let ty = ty_from_hir_ty ( cx, hir_ty. as_unambig_ty ( ) )
218220 && let impl_ty = cx. tcx . type_of ( impl_id) . instantiate_identity ( )
@@ -312,6 +314,38 @@ fn lint_path_to_variant(cx: &LateContext<'_>, path: &Path<'_>) {
312314 }
313315}
314316
317+ fn ty_is_in_generic_args < ' tcx > ( cx : & LateContext < ' tcx > , hir_ty : & Ty < ' tcx , AmbigArg > ) -> bool {
318+ cx. tcx . hir_parent_iter ( hir_ty. hir_id ) . any ( |( _, parent) | {
319+ matches ! ( parent, Node :: ImplItem ( impl_item) if impl_item. generics. params. iter( ) . any( |param| {
320+ let GenericParamKind :: Const { ty: const_ty, .. } = & param. kind else {
321+ return false ;
322+ } ;
323+ ty_contains_ty( const_ty, hir_ty)
324+ } ) )
325+ } )
326+ }
327+
328+ fn ty_contains_ty < ' tcx > ( outer : & Ty < ' tcx > , inner : & Ty < ' tcx , AmbigArg > ) -> bool {
329+ struct ContainsVisitor < ' tcx > {
330+ inner : & ' tcx Ty < ' tcx , AmbigArg > ,
331+ }
332+
333+ impl < ' tcx > Visitor < ' tcx > for ContainsVisitor < ' tcx > {
334+ type Result = ControlFlow < ( ) > ;
335+
336+ fn visit_ty ( & mut self , t : & ' tcx Ty < ' tcx , AmbigArg > ) -> Self :: Result {
337+ if t. hir_id == self . inner . hir_id {
338+ return ControlFlow :: Break ( ( ) ) ;
339+ }
340+
341+ walk_ty ( self , t)
342+ }
343+ }
344+
345+ let mut visitor = ContainsVisitor { inner } ;
346+ visitor. visit_ty_unambig ( outer) . is_break ( )
347+ }
348+
315349/// Checks whether types `a` and `b` have the same lifetime parameters.
316350///
317351/// This function does not check that types `a` and `b` are the same types.
0 commit comments