Skip to content

Commit caf65b1

Browse files
committed
fix: use_self FP on type in const generics
1 parent 65c339e commit caf65b1

File tree

4 files changed

+120
-43
lines changed

4 files changed

+120
-43
lines changed

clippy_lints/src/use_self.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_hir::def_id::LocalDefId;
1010
use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_ty};
1111
use 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
};
1515
use rustc_lint::{LateContext, LateLintPass};
1616
use rustc_middle::ty::Ty as MiddleTy;
@@ -213,6 +213,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
213213
path.res,
214214
Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Def(DefKind::TyParam, _)
215215
)
216+
&& !ty_is_in_generic_args(cx, hir_ty)
216217
&& !types_to_skip.contains(&hir_ty.hir_id)
217218
&& let ty = ty_from_hir_ty(cx, hir_ty.as_unambig_ty())
218219
&& let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity()
@@ -312,6 +313,32 @@ fn lint_path_to_variant(cx: &LateContext<'_>, path: &Path<'_>) {
312313
}
313314
}
314315

316+
fn ty_is_in_generic_args<'tcx>(cx: &LateContext<'tcx>, hir_ty: &Ty<'tcx, AmbigArg>) -> bool {
317+
cx.tcx.hir_parent_iter(hir_ty.hir_id).any(|(_, parent)| {
318+
matches!(parent, Node::ImplItem(impl_item) if impl_item.generics.params.iter().any(|param| {
319+
let GenericParamKind::Const { ty: const_ty, .. } = &param.kind else {
320+
return false;
321+
};
322+
ty_contains_ty(const_ty, hir_ty)
323+
}))
324+
})
325+
}
326+
327+
fn ty_contains_ty<'tcx>(outer: &Ty<'tcx>, inner: &Ty<'tcx, AmbigArg>) -> bool {
328+
if outer.hir_id == inner.hir_id {
329+
return true;
330+
}
331+
332+
match &outer.kind {
333+
TyKind::Array(element_ty, _)
334+
| TyKind::Slice(element_ty)
335+
| TyKind::Ptr(hir::MutTy { ty: element_ty, .. })
336+
| TyKind::Ref(_, hir::MutTy { ty: element_ty, .. }) => ty_contains_ty(element_ty, inner),
337+
TyKind::Tup(element_tys) => element_tys.iter().any(|ty| ty_contains_ty(ty, inner)),
338+
_ => false, // TODO: handle more cases if needed
339+
}
340+
}
341+
315342
/// Checks whether types `a` and `b` have the same lifetime parameters.
316343
///
317344
/// This function does not check that types `a` and `b` are the same types.

tests/ui/use_self.fixed

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
clippy::needless_lifetimes,
1111
clippy::missing_transmute_annotations
1212
)]
13+
#![allow(incomplete_features)]
14+
#![feature(adt_const_params)]
15+
#![feature(unsized_const_params)]
1316

1417
#[macro_use]
1518
extern crate proc_macro_derive;
@@ -769,3 +772,25 @@ mod issue_13277 {
769772
type Item<'foo> = Option<Bar<'foo>>;
770773
}
771774
}
775+
776+
mod issue16164 {
777+
trait Bits {
778+
fn bit<const I: u8>(self) -> bool;
779+
}
780+
781+
impl Bits for u8 {
782+
fn bit<const I: u8>(self) -> bool {
783+
todo!()
784+
}
785+
}
786+
787+
trait T {
788+
fn f<const C: (u8, u8)>(self) -> bool;
789+
}
790+
791+
impl T for u8 {
792+
fn f<const C: (u8, u8)>(self) -> bool {
793+
todo!()
794+
}
795+
}
796+
}

tests/ui/use_self.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
clippy::needless_lifetimes,
1111
clippy::missing_transmute_annotations
1212
)]
13+
#![allow(incomplete_features)]
14+
#![feature(adt_const_params)]
15+
#![feature(unsized_const_params)]
1316

1417
#[macro_use]
1518
extern crate proc_macro_derive;
@@ -769,3 +772,25 @@ mod issue_13277 {
769772
type Item<'foo> = Option<Bar<'foo>>;
770773
}
771774
}
775+
776+
mod issue16164 {
777+
trait Bits {
778+
fn bit<const I: u8>(self) -> bool;
779+
}
780+
781+
impl Bits for u8 {
782+
fn bit<const I: u8>(self) -> bool {
783+
todo!()
784+
}
785+
}
786+
787+
trait T {
788+
fn f<const C: (u8, u8)>(self) -> bool;
789+
}
790+
791+
impl T for u8 {
792+
fn f<const C: (u8, u8)>(self) -> bool {
793+
todo!()
794+
}
795+
}
796+
}

0 commit comments

Comments
 (0)