about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSamuel Tardieu <sam@rfc1149.net>2023-02-19 11:54:12 +0100
committerSamuel Tardieu <sam@rfc1149.net>2023-02-19 11:59:02 +0100
commitf531abcef52c3c3ab283eb82a9487d5e9192bf12 (patch)
treed9bd5bd4c46f924dad2f160c95fbd54888a216f1
parent85d4b5ac4855433fdb7584285db4f0af65805041 (diff)
downloadrust-f531abcef52c3c3ab283eb82a9487d5e9192bf12.tar.gz
rust-f531abcef52c3c3ab283eb82a9487d5e9192bf12.zip
Do not suggest using Self in const generic parameters
-rw-r--r--clippy_lints/src/use_self.rs15
-rw-r--r--tests/ui/use_self.fixed10
-rw-r--r--tests/ui/use_self.rs10
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<const V: i32> {}
+
+    impl<const V: i32> From<Val<V>> for i32 {
+        fn from(_: Val<V>) -> 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<const V: i32> {}
+
+    impl<const V: i32> From<Val<V>> for i32 {
+        fn from(_: Val<V>) -> Self {
+            todo!()
+        }
+    }
+}