From caf65b11420e9e1ede3604a9016aa94600ac06e4 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Mon, 1 Dec 2025 22:49:41 +0000 Subject: [PATCH] fix: `use_self` FP on type in const generics --- clippy_lints/src/use_self.rs | 29 ++++++++++++- tests/ui/use_self.fixed | 25 +++++++++++ tests/ui/use_self.rs | 25 +++++++++++ tests/ui/use_self.stderr | 84 ++++++++++++++++++------------------ 4 files changed, 120 insertions(+), 43 deletions(-) diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index eba60501ae21..1ee00fc25756 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -10,7 +10,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_ty}; use rustc_hir::{ self as hir, AmbigArg, Expr, ExprKind, FnRetTy, FnSig, GenericArgsParentheses, GenericParamKind, HirId, Impl, - ImplItemImplKind, ImplItemKind, Item, ItemKind, Pat, PatExpr, PatExprKind, PatKind, Path, QPath, Ty, TyKind, + ImplItemImplKind, ImplItemKind, Item, ItemKind, Node, Pat, PatExpr, PatExprKind, PatKind, Path, QPath, Ty, TyKind, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::Ty as MiddleTy; @@ -213,6 +213,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { path.res, Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Def(DefKind::TyParam, _) ) + && !ty_is_in_generic_args(cx, hir_ty) && !types_to_skip.contains(&hir_ty.hir_id) && let ty = ty_from_hir_ty(cx, hir_ty.as_unambig_ty()) && let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity() @@ -312,6 +313,32 @@ fn lint_path_to_variant(cx: &LateContext<'_>, path: &Path<'_>) { } } +fn ty_is_in_generic_args<'tcx>(cx: &LateContext<'tcx>, hir_ty: &Ty<'tcx, AmbigArg>) -> bool { + cx.tcx.hir_parent_iter(hir_ty.hir_id).any(|(_, parent)| { + matches!(parent, Node::ImplItem(impl_item) if impl_item.generics.params.iter().any(|param| { + let GenericParamKind::Const { ty: const_ty, .. } = ¶m.kind else { + return false; + }; + ty_contains_ty(const_ty, hir_ty) + })) + }) +} + +fn ty_contains_ty<'tcx>(outer: &Ty<'tcx>, inner: &Ty<'tcx, AmbigArg>) -> bool { + if outer.hir_id == inner.hir_id { + return true; + } + + match &outer.kind { + TyKind::Array(element_ty, _) + | TyKind::Slice(element_ty) + | TyKind::Ptr(hir::MutTy { ty: element_ty, .. }) + | TyKind::Ref(_, hir::MutTy { ty: element_ty, .. }) => ty_contains_ty(element_ty, inner), + TyKind::Tup(element_tys) => element_tys.iter().any(|ty| ty_contains_ty(ty, inner)), + _ => false, // TODO: handle more cases if needed + } +} + /// Checks whether types `a` and `b` have the same lifetime parameters. /// /// This function does not check that types `a` and `b` are the same types. diff --git a/tests/ui/use_self.fixed b/tests/ui/use_self.fixed index 075e31d202b0..37559f9a2367 100644 --- a/tests/ui/use_self.fixed +++ b/tests/ui/use_self.fixed @@ -10,6 +10,9 @@ clippy::needless_lifetimes, clippy::missing_transmute_annotations )] +#![allow(incomplete_features)] +#![feature(adt_const_params)] +#![feature(unsized_const_params)] #[macro_use] extern crate proc_macro_derive; @@ -769,3 +772,25 @@ mod issue_13277 { type Item<'foo> = Option>; } } + +mod issue16164 { + trait Bits { + fn bit(self) -> bool; + } + + impl Bits for u8 { + fn bit(self) -> bool { + todo!() + } + } + + trait T { + fn f(self) -> bool; + } + + impl T for u8 { + fn f(self) -> bool { + todo!() + } + } +} diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs index 6fbba0bbc550..74abd2f61bf9 100644 --- a/tests/ui/use_self.rs +++ b/tests/ui/use_self.rs @@ -10,6 +10,9 @@ clippy::needless_lifetimes, clippy::missing_transmute_annotations )] +#![allow(incomplete_features)] +#![feature(adt_const_params)] +#![feature(unsized_const_params)] #[macro_use] extern crate proc_macro_derive; @@ -769,3 +772,25 @@ mod issue_13277 { type Item<'foo> = Option>; } } + +mod issue16164 { + trait Bits { + fn bit(self) -> bool; + } + + impl Bits for u8 { + fn bit(self) -> bool { + todo!() + } + } + + trait T { + fn f(self) -> bool; + } + + impl T for u8 { + fn f(self) -> bool { + todo!() + } + } +} diff --git a/tests/ui/use_self.stderr b/tests/ui/use_self.stderr index 5f65c53ea25c..8ce341d22d4f 100644 --- a/tests/ui/use_self.stderr +++ b/tests/ui/use_self.stderr @@ -1,5 +1,5 @@ error: unnecessary structure name repetition - --> tests/ui/use_self.rs:23:21 + --> tests/ui/use_self.rs:26:21 | LL | fn new() -> Foo { | ^^^ help: use the applicable keyword: `Self` @@ -8,247 +8,247 @@ LL | fn new() -> Foo { = help: to override `-D warnings` add `#[allow(clippy::use_self)]` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:25:13 + --> tests/ui/use_self.rs:28:13 | LL | Foo {} | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:28:22 + --> tests/ui/use_self.rs:31:22 | LL | fn test() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:30:13 + --> tests/ui/use_self.rs:33:13 | LL | Foo::new() | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:36:25 + --> tests/ui/use_self.rs:39:25 | LL | fn default() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:38:13 + --> tests/ui/use_self.rs:41:13 | LL | Foo::new() | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:80:28 + --> tests/ui/use_self.rs:83:28 | LL | fn clone(&self) -> Foo<'a> { | ^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:114:24 + --> tests/ui/use_self.rs:117:24 | LL | fn bad(foos: &[Foo]) -> impl Iterator { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:114:55 + --> tests/ui/use_self.rs:117:55 | LL | fn bad(foos: &[Foo]) -> impl Iterator { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:131:13 + --> tests/ui/use_self.rs:134:13 | LL | TS(0) | ^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:167:29 + --> tests/ui/use_self.rs:170:29 | LL | fn bar() -> Bar { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:169:21 + --> tests/ui/use_self.rs:172:21 | LL | Bar { foo: Foo {} } | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:181:21 + --> tests/ui/use_self.rs:184:21 | LL | fn baz() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:183:13 + --> tests/ui/use_self.rs:186:13 | LL | Foo {} | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:201:21 + --> tests/ui/use_self.rs:204:21 | LL | let _ = Enum::B(42); | ^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:203:21 + --> tests/ui/use_self.rs:206:21 | LL | let _ = Enum::C { field: true }; | ^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:205:21 + --> tests/ui/use_self.rs:208:21 | LL | let _ = Enum::A; | ^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:248:13 + --> tests/ui/use_self.rs:251:13 | LL | nested::A::fun_1(); | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:250:13 + --> tests/ui/use_self.rs:253:13 | LL | nested::A::A; | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:253:13 + --> tests/ui/use_self.rs:256:13 | LL | nested::A {}; | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:273:13 + --> tests/ui/use_self.rs:276:13 | LL | TestStruct::from_something() | ^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:288:25 + --> tests/ui/use_self.rs:291:25 | LL | async fn g() -> S { | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:290:13 + --> tests/ui/use_self.rs:293:13 | LL | S {} | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:295:16 + --> tests/ui/use_self.rs:298:16 | LL | &p[S::A..S::B] | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:295:22 + --> tests/ui/use_self.rs:298:22 | LL | &p[S::A..S::B] | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:320:29 + --> tests/ui/use_self.rs:323:29 | LL | fn foo(value: T) -> Foo { | ^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:322:13 + --> tests/ui/use_self.rs:325:13 | LL | Foo:: { value } | ^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:495:13 + --> tests/ui/use_self.rs:498:13 | LL | A::new::(submod::B {}) | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:571:17 + --> tests/ui/use_self.rs:574:17 | LL | Foo::Bar => unimplemented!(), | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:573:17 + --> tests/ui/use_self.rs:576:17 | LL | Foo::Baz => unimplemented!(), | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:580:20 + --> tests/ui/use_self.rs:583:20 | LL | if let Foo::Bar = self { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:605:17 + --> tests/ui/use_self.rs:608:17 | LL | Something::Num(n) => *n, | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:607:17 + --> tests/ui/use_self.rs:610:17 | LL | Something::TupleNums(n, _m) => *n, | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:609:17 + --> tests/ui/use_self.rs:612:17 | LL | Something::StructNums { one, two: _ } => *one, | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:616:17 + --> tests/ui/use_self.rs:619:17 | LL | crate::issue8845::Something::Num(n) => *n, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:618:17 + --> tests/ui/use_self.rs:621:17 | LL | crate::issue8845::Something::TupleNums(n, _m) => *n, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:620:17 + --> tests/ui/use_self.rs:623:17 | LL | crate::issue8845::Something::StructNums { one, two: _ } => *one, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:637:17 + --> tests/ui/use_self.rs:640:17 | LL | let Foo(x) = self; | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:643:17 + --> tests/ui/use_self.rs:646:17 | LL | let crate::issue8845::Foo(x) = self; | ^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:651:17 + --> tests/ui/use_self.rs:654:17 | LL | let Bar { x, .. } = self; | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:657:17 + --> tests/ui/use_self.rs:660:17 | LL | let crate::issue8845::Bar { x, .. } = self; | ^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:697:17 + --> tests/ui/use_self.rs:700:17 | LL | E::A => {}, | ^ help: use the applicable keyword: `Self`