Skip to content

Commit cf267e5

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

File tree

4 files changed

+127
-43
lines changed

4 files changed

+127
-43
lines changed

clippy_lints/src/use_self.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@ 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;
1717
use rustc_session::impl_lint_pass;
1818
use rustc_span::Span;
1919
use std::iter;
20+
use std::ops::ControlFlow;
2021

2122
declare_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.

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)