about summary refs log tree commit diff
diff options
context:
space:
mode:
authoryanglsh <yanglsh@shanghaitech.edu.cn>2025-03-13 16:49:34 +0800
committeryanglsh <yanglsh@shanghaitech.edu.cn>2025-03-29 20:52:59 +0800
commit2df6bba5b06dfb073b93199517803a6bd0aa15a0 (patch)
treecd29e11f96f602f834f6999a67048ec6413ea7d0
parentc033a4c741bc7e8db0ffa49c110377f602d5c61c (diff)
downloadrust-2df6bba5b06dfb073b93199517803a6bd0aa15a0.tar.gz
rust-2df6bba5b06dfb073b93199517803a6bd0aa15a0.zip
fix: `unnested_or_patterns` suggests wrongly in `let`
-rw-r--r--clippy_lints/src/unnested_or_patterns.rs13
-rw-r--r--tests/ui/unnested_or_patterns.fixed13
-rw-r--r--tests/ui/unnested_or_patterns.rs13
-rw-r--r--tests/ui/unnested_or_patterns.stderr38
4 files changed, 73 insertions, 4 deletions
diff --git a/clippy_lints/src/unnested_or_patterns.rs b/clippy_lints/src/unnested_or_patterns.rs
index f43715d6752..913a67b18a6 100644
--- a/clippy_lints/src/unnested_or_patterns.rs
+++ b/clippy_lints/src/unnested_or_patterns.rs
@@ -120,18 +120,25 @@ fn lint_unnested_or_patterns(cx: &EarlyContext<'_>, pat: &Pat) {
 
 /// Remove all `(p)` patterns in `pat`.
 fn remove_all_parens(pat: &mut P<Pat>) {
-    struct Visitor;
+    #[derive(Default)]
+    struct Visitor {
+        /// If is not in the outer most pattern. This is needed to avoid removing the outermost
+        /// parens because top-level or-patterns are not allowed in let statements.
+        is_inner: bool,
+    }
+
     impl MutVisitor for Visitor {
         fn visit_pat(&mut self, pat: &mut P<Pat>) {
+            let is_inner = mem::replace(&mut self.is_inner, true);
             walk_pat(self, pat);
             let inner = match &mut pat.kind {
-                Paren(i) => mem::replace(&mut i.kind, Wild),
+                Paren(i) if is_inner => mem::replace(&mut i.kind, Wild),
                 _ => return,
             };
             pat.kind = inner;
         }
     }
-    Visitor.visit_pat(pat);
+    Visitor::default().visit_pat(pat);
 }
 
 /// Insert parens where necessary according to Rust's precedence rules for patterns.
diff --git a/tests/ui/unnested_or_patterns.fixed b/tests/ui/unnested_or_patterns.fixed
index 791b2fa131f..2081772d06b 100644
--- a/tests/ui/unnested_or_patterns.fixed
+++ b/tests/ui/unnested_or_patterns.fixed
@@ -64,3 +64,16 @@ fn msrv_1_53() {
     if let [1 | 53] = [0] {}
     //~^ unnested_or_patterns
 }
+
+mod issue9952 {
+    fn or_in_local() {
+        let (0 | 1 | _) = 0;
+        //~^ unnested_or_patterns
+
+        if let (0 | 1 | _) = 0 {}
+        //~^ unnested_or_patterns
+    }
+
+    fn or_in_param((x | x | x): i32) {}
+    //~^ unnested_or_patterns
+}
diff --git a/tests/ui/unnested_or_patterns.rs b/tests/ui/unnested_or_patterns.rs
index e7e7c7cd2e4..6bf8fce3661 100644
--- a/tests/ui/unnested_or_patterns.rs
+++ b/tests/ui/unnested_or_patterns.rs
@@ -64,3 +64,16 @@ fn msrv_1_53() {
     if let [1] | [53] = [0] {}
     //~^ unnested_or_patterns
 }
+
+mod issue9952 {
+    fn or_in_local() {
+        let (0 | (1 | _)) = 0;
+        //~^ unnested_or_patterns
+
+        if let (0 | (1 | _)) = 0 {}
+        //~^ unnested_or_patterns
+    }
+
+    fn or_in_param((x | (x | x)): i32) {}
+    //~^ unnested_or_patterns
+}
diff --git a/tests/ui/unnested_or_patterns.stderr b/tests/ui/unnested_or_patterns.stderr
index ec5eb983c5a..c805dc992b1 100644
--- a/tests/ui/unnested_or_patterns.stderr
+++ b/tests/ui/unnested_or_patterns.stderr
@@ -204,5 +204,41 @@ LL -     if let [1] | [53] = [0] {}
 LL +     if let [1 | 53] = [0] {}
    |
 
-error: aborting due to 17 previous errors
+error: unnested or-patterns
+  --> tests/ui/unnested_or_patterns.rs:70:13
+   |
+LL |         let (0 | (1 | _)) = 0;
+   |             ^^^^^^^^^^^^^
+   |
+help: nest the patterns
+   |
+LL -         let (0 | (1 | _)) = 0;
+LL +         let (0 | 1 | _) = 0;
+   |
+
+error: unnested or-patterns
+  --> tests/ui/unnested_or_patterns.rs:73:16
+   |
+LL |         if let (0 | (1 | _)) = 0 {}
+   |                ^^^^^^^^^^^^^
+   |
+help: nest the patterns
+   |
+LL -         if let (0 | (1 | _)) = 0 {}
+LL +         if let (0 | 1 | _) = 0 {}
+   |
+
+error: unnested or-patterns
+  --> tests/ui/unnested_or_patterns.rs:77:20
+   |
+LL |     fn or_in_param((x | (x | x)): i32) {}
+   |                    ^^^^^^^^^^^^^
+   |
+help: nest the patterns
+   |
+LL -     fn or_in_param((x | (x | x)): i32) {}
+LL +     fn or_in_param((x | x | x): i32) {}
+   |
+
+error: aborting due to 20 previous errors