Fix use_self FP on type in const generics (#16172)

Closes rust-lang/rust-clippy#16164

changelog: [`use_self`] fix FP on type in const generics
This commit is contained in:
Samuel Tardieu 2025-12-22 08:28:21 +00:00 committed by GitHub
commit b193e4fa05
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 127 additions and 43 deletions

View file

@ -10,13 +10,14 @@ 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;
use rustc_session::impl_lint_pass;
use rustc_span::Span;
use std::iter;
use std::ops::ControlFlow;
declare_clippy_lint! {
/// ### What it does
@ -213,6 +214,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 +314,38 @@ 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, .. } = &param.kind else {
return false;
};
ty_contains_ty(const_ty, hir_ty)
}))
})
}
fn ty_contains_ty<'tcx>(outer: &Ty<'tcx>, inner: &Ty<'tcx, AmbigArg>) -> bool {
struct ContainsVisitor<'tcx> {
inner: &'tcx Ty<'tcx, AmbigArg>,
}
impl<'tcx> Visitor<'tcx> for ContainsVisitor<'tcx> {
type Result = ControlFlow<()>;
fn visit_ty(&mut self, t: &'tcx Ty<'tcx, AmbigArg>) -> Self::Result {
if t.hir_id == self.inner.hir_id {
return ControlFlow::Break(());
}
walk_ty(self, t)
}
}
let mut visitor = ContainsVisitor { inner };
visitor.visit_ty_unambig(outer).is_break()
}
/// 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.

View file

@ -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<Bar<'foo>>;
}
}
mod issue16164 {
trait Bits {
fn bit<const I: u8>(self) -> bool;
}
impl Bits for u8 {
fn bit<const I: u8>(self) -> bool {
todo!()
}
}
trait T {
fn f<const C: (u8, u8)>(self) -> bool;
}
impl T for u8 {
fn f<const C: (u8, u8)>(self) -> bool {
todo!()
}
}
}

View file

@ -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<Bar<'foo>>;
}
}
mod issue16164 {
trait Bits {
fn bit<const I: u8>(self) -> bool;
}
impl Bits for u8 {
fn bit<const I: u8>(self) -> bool {
todo!()
}
}
trait T {
fn f<const C: (u8, u8)>(self) -> bool;
}
impl T for u8 {
fn f<const C: (u8, u8)>(self) -> bool {
todo!()
}
}
}

View file

@ -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<Item = &Foo> {
| ^^^ 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<Item = &Foo> {
| ^^^ 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<T> {
| ^^^^^^ 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::<T> { 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>(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`