Skip to content

Commit dc14141

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

File tree

4 files changed

+134
-43
lines changed

4 files changed

+134
-43
lines changed

clippy_lints/src/use_self.rs

Lines changed: 42 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,46 @@ 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+
struct ContainsVisitor<'tcx> {
329+
inner: &'tcx Ty<'tcx, AmbigArg>,
330+
found: bool,
331+
}
332+
333+
impl<'tcx> Visitor<'tcx> for ContainsVisitor<'tcx> {
334+
fn visit_ty(&mut self, t: &'tcx Ty<'tcx, AmbigArg>) {
335+
if self.found {
336+
return;
337+
}
338+
339+
if t.hir_id == self.inner.hir_id {
340+
self.found = true;
341+
return;
342+
}
343+
344+
walk_ty(self, t);
345+
}
346+
}
347+
348+
let Some(outer) = outer.try_as_ambig_ty() else {
349+
return false;
350+
};
351+
let mut visitor = ContainsVisitor { inner, found: false };
352+
visitor.visit_ty(outer);
353+
visitor.found
354+
}
355+
315356
/// Checks whether types `a` and `b` have the same lifetime parameters.
316357
///
317358
/// 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)