about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTimo <30553356+y21@users.noreply.github.com>2025-05-26 18:13:29 +0000
committerGitHub <noreply@github.com>2025-05-26 18:13:29 +0000
commitb719f99090dd1472feba81bf52b6ac2e67bb0b30 (patch)
tree610a36ff441c55071bf24a77dbffc2c4b965ab5d
parent32a3744efc15f5bb3024cefbb2641fe238f319f2 (diff)
parent843a45f384f3e285c8c60ac5780b19be88435538 (diff)
downloadrust-b719f99090dd1472feba81bf52b6ac2e67bb0b30.tar.gz
rust-b719f99090dd1472feba81bf52b6ac2e67bb0b30.zip
Consider consts in patterns as refutable (#14887)
changelog: none
-rw-r--r--clippy_utils/src/lib.rs14
-rw-r--r--tests/ui/question_mark.fixed10
-rw-r--r--tests/ui/question_mark.rs10
3 files changed, 28 insertions, 6 deletions
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index 3a319176571..42136fdbc51 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -1565,10 +1565,10 @@ pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_>, expr: &Expr<'_
 /// Returns `true` if a pattern is refutable.
 // TODO: should be implemented using rustc/mir_build/thir machinery
 pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
-    fn is_enum_variant(cx: &LateContext<'_>, qpath: &QPath<'_>, id: HirId) -> bool {
-        matches!(
+    fn is_qpath_refutable(cx: &LateContext<'_>, qpath: &QPath<'_>, id: HirId) -> bool {
+        !matches!(
             cx.qpath_res(qpath, id),
-            Res::Def(DefKind::Variant, ..) | Res::Def(DefKind::Ctor(def::CtorOf::Variant, _), _)
+            Res::Def(DefKind::Struct, ..) | Res::Def(DefKind::Ctor(def::CtorOf::Struct, _), _)
         )
     }
 
@@ -1585,16 +1585,18 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
             kind: PatExprKind::Path(qpath),
             hir_id,
             ..
-        }) => is_enum_variant(cx, qpath, *hir_id),
+        }) => is_qpath_refutable(cx, qpath, *hir_id),
         PatKind::Or(pats) => {
             // TODO: should be the honest check, that pats is exhaustive set
             are_refutable(cx, pats)
         },
         PatKind::Tuple(pats, _) => are_refutable(cx, pats),
         PatKind::Struct(ref qpath, fields, _) => {
-            is_enum_variant(cx, qpath, pat.hir_id) || are_refutable(cx, fields.iter().map(|field| field.pat))
+            is_qpath_refutable(cx, qpath, pat.hir_id) || are_refutable(cx, fields.iter().map(|field| field.pat))
+        },
+        PatKind::TupleStruct(ref qpath, pats, _) => {
+            is_qpath_refutable(cx, qpath, pat.hir_id) || are_refutable(cx, pats)
         },
-        PatKind::TupleStruct(ref qpath, pats, _) => is_enum_variant(cx, qpath, pat.hir_id) || are_refutable(cx, pats),
         PatKind::Slice(head, middle, tail) => {
             match &cx.typeck_results().node_type(pat.hir_id).kind() {
                 rustc_ty::Slice(..) => {
diff --git a/tests/ui/question_mark.fixed b/tests/ui/question_mark.fixed
index 507bc2b29d8..60dc1c101b6 100644
--- a/tests/ui/question_mark.fixed
+++ b/tests/ui/question_mark.fixed
@@ -443,3 +443,13 @@ fn issue_14615(a: MutexGuard<Option<u32>>) -> Option<String> {
     //~^^^ question_mark
     Some(format!("{a}"))
 }
+
+fn const_in_pattern(x: Option<(i32, i32)>) -> Option<()> {
+    const N: i32 = 0;
+
+    let Some((x, N)) = x else {
+        return None;
+    };
+
+    None
+}
diff --git a/tests/ui/question_mark.rs b/tests/ui/question_mark.rs
index 64b51b849ed..99d0122a98f 100644
--- a/tests/ui/question_mark.rs
+++ b/tests/ui/question_mark.rs
@@ -539,3 +539,13 @@ fn issue_14615(a: MutexGuard<Option<u32>>) -> Option<String> {
     //~^^^ question_mark
     Some(format!("{a}"))
 }
+
+fn const_in_pattern(x: Option<(i32, i32)>) -> Option<()> {
+    const N: i32 = 0;
+
+    let Some((x, N)) = x else {
+        return None;
+    };
+
+    None
+}