From f531abcef52c3c3ab283eb82a9487d5e9192bf12 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sun, 19 Feb 2023 11:54:12 +0100 Subject: [PATCH] Do not suggest using Self in const generic parameters --- clippy_lints/src/use_self.rs | 15 +++++++++++---- tests/ui/use_self.fixed | 10 ++++++++++ tests/ui/use_self.rs | 10 ++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index 3cd35838961..8f2b4a7eafb 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -10,8 +10,8 @@ use rustc_hir::{ def::{CtorOf, DefKind, Res}, def_id::LocalDefId, intravisit::{walk_inf, walk_ty, Visitor}, - Expr, ExprKind, FnRetTy, FnSig, GenericArg, HirId, Impl, ImplItemKind, Item, ItemKind, Pat, PatKind, Path, QPath, - TyKind, + Expr, ExprKind, FnRetTy, FnSig, GenericArg, GenericParam, GenericParamKind, HirId, Impl, ImplItemKind, Item, + ItemKind, Pat, PatKind, Path, QPath, Ty, TyKind, }; use rustc_hir_analysis::hir_ty_to_ty; use rustc_lint::{LateContext, LateLintPass}; @@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { // avoid linting on nested items, we push `StackItem::NoCheck` on the stack to signal, that // we're in an `impl` or nested item, that we don't want to lint let stack_item = if_chain! { - if let ItemKind::Impl(Impl { self_ty, .. }) = item.kind; + if let ItemKind::Impl(Impl { self_ty, generics,.. }) = item.kind; if let TyKind::Path(QPath::Resolved(_, item_path)) = self_ty.kind; let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args; if parameters.as_ref().map_or(true, |params| { @@ -105,10 +105,17 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { if !item.span.from_expansion(); if !is_from_proc_macro(cx, item); // expensive, should be last check then { + // Self cannot be used inside const generic parameters + let types_to_skip = generics.params.iter().filter_map(|param| { + match param { + GenericParam { kind: GenericParamKind::Const { ty: Ty { hir_id, ..}, ..}, ..} => Some(*hir_id), + _ => None, + } + }).chain(std::iter::once(self_ty.hir_id)).collect(); StackItem::Check { impl_id: item.owner_id.def_id, in_body: 0, - types_to_skip: std::iter::once(self_ty.hir_id).collect(), + types_to_skip, } } else { StackItem::NoCheck diff --git a/tests/ui/use_self.fixed b/tests/ui/use_self.fixed index 0a6166571eb..3ac6217312a 100644 --- a/tests/ui/use_self.fixed +++ b/tests/ui/use_self.fixed @@ -647,3 +647,13 @@ fn msrv_1_37() { } } } + +mod issue_10371 { + struct Val {} + + impl From> for i32 { + fn from(_: Val) -> Self { + todo!() + } + } +} diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs index 39c2b431f7f..9dc5d1e3f9b 100644 --- a/tests/ui/use_self.rs +++ b/tests/ui/use_self.rs @@ -647,3 +647,13 @@ fn msrv_1_37() { } } } + +mod issue_10371 { + struct Val {} + + impl From> for i32 { + fn from(_: Val) -> Self { + todo!() + } + } +}