about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_lint/src/unused.rs16
-rw-r--r--tests/ui/lint/unused-parens-for-macro-call-with-brace.fixed28
-rw-r--r--tests/ui/lint/unused-parens-for-macro-call-with-brace.rs28
-rw-r--r--tests/ui/lint/unused-parens-for-macro-call-with-brace.stderr67
4 files changed, 139 insertions, 0 deletions
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 806bca78f78..50a27d7e84f 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -942,6 +942,22 @@ trait UnusedDelimLint {
         match s.kind {
             StmtKind::Let(ref local) if Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX => {
                 if let Some((init, els)) = local.kind.init_else_opt() {
+                    if els.is_some()
+                        && let ExprKind::Paren(paren) = &init.kind
+                        && !init.span.eq_ctxt(paren.span)
+                    {
+                        // This branch prevents cases where parentheses wrap an expression
+                        // resulting from macro expansion, such as:
+                        // ```
+                        // macro_rules! x {
+                        // () => { None::<i32> };
+                        // }
+                        // let Some(_) = (x!{}) else { return };
+                        // // -> let Some(_) = (None::<i32>) else { return };
+                        // //                  ~           ~ No Lint
+                        // ```
+                        return;
+                    }
                     let ctx = match els {
                         None => UnusedDelimsCtx::AssignedValue,
                         Some(_) => UnusedDelimsCtx::AssignedValueLetElse,
diff --git a/tests/ui/lint/unused-parens-for-macro-call-with-brace.fixed b/tests/ui/lint/unused-parens-for-macro-call-with-brace.fixed
new file mode 100644
index 00000000000..4c9995fcb61
--- /dev/null
+++ b/tests/ui/lint/unused-parens-for-macro-call-with-brace.fixed
@@ -0,0 +1,28 @@
+//@ run-rustfix
+
+#![deny(unused_parens)]
+
+fn main() {
+    macro_rules! x {
+        () => { None::<i32> };
+    }
+
+    let Some(_) = (x!{}) else { return }; // no error
+    let Some(_) = (x!{}) else { return };
+    //~^ ERROR: unnecessary parentheses around assigned value
+
+    let Some(_) = (x!{}) else { return };
+    //~^ ERROR: unnecessary parentheses around pattern
+
+    let _ = x!{};
+    let _ = x!{};
+    //~^ ERROR: unnecessary parentheses around assigned value
+
+    if let Some(_) = x!{} {};
+    if let Some(_) = x!{} {};
+    //~^ ERROR: unnecessary parentheses around `let` scrutinee expression
+
+    while let Some(_) = x!{} {};
+    while let Some(_) = x!{} {};
+    //~^ ERROR: unnecessary parentheses around `let` scrutinee expression
+}
diff --git a/tests/ui/lint/unused-parens-for-macro-call-with-brace.rs b/tests/ui/lint/unused-parens-for-macro-call-with-brace.rs
new file mode 100644
index 00000000000..59e215a48cc
--- /dev/null
+++ b/tests/ui/lint/unused-parens-for-macro-call-with-brace.rs
@@ -0,0 +1,28 @@
+//@ run-rustfix
+
+#![deny(unused_parens)]
+
+fn main() {
+    macro_rules! x {
+        () => { None::<i32> };
+    }
+
+    let Some(_) = (x!{}) else { return }; // no error
+    let Some(_) = ((x!{})) else { return };
+    //~^ ERROR: unnecessary parentheses around assigned value
+
+    let Some((_)) = (x!{}) else { return };
+    //~^ ERROR: unnecessary parentheses around pattern
+
+    let _ = x!{};
+    let _ = (x!{});
+    //~^ ERROR: unnecessary parentheses around assigned value
+
+    if let Some(_) = x!{} {};
+    if let Some(_) = (x!{}) {};
+    //~^ ERROR: unnecessary parentheses around `let` scrutinee expression
+
+    while let Some(_) = x!{} {};
+    while let Some(_) = (x!{}) {};
+    //~^ ERROR: unnecessary parentheses around `let` scrutinee expression
+}
diff --git a/tests/ui/lint/unused-parens-for-macro-call-with-brace.stderr b/tests/ui/lint/unused-parens-for-macro-call-with-brace.stderr
new file mode 100644
index 00000000000..8d3b4fe493e
--- /dev/null
+++ b/tests/ui/lint/unused-parens-for-macro-call-with-brace.stderr
@@ -0,0 +1,67 @@
+error: unnecessary parentheses around assigned value
+  --> $DIR/unused-parens-for-macro-call-with-brace.rs:11:19
+   |
+LL |     let Some(_) = ((x!{})) else { return };
+   |                   ^      ^
+   |
+note: the lint level is defined here
+  --> $DIR/unused-parens-for-macro-call-with-brace.rs:3:9
+   |
+LL | #![deny(unused_parens)]
+   |         ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     let Some(_) = ((x!{})) else { return };
+LL +     let Some(_) = (x!{}) else { return };
+   |
+
+error: unnecessary parentheses around pattern
+  --> $DIR/unused-parens-for-macro-call-with-brace.rs:14:14
+   |
+LL |     let Some((_)) = (x!{}) else { return };
+   |              ^ ^
+   |
+help: remove these parentheses
+   |
+LL -     let Some((_)) = (x!{}) else { return };
+LL +     let Some(_) = (x!{}) else { return };
+   |
+
+error: unnecessary parentheses around assigned value
+  --> $DIR/unused-parens-for-macro-call-with-brace.rs:18:13
+   |
+LL |     let _ = (x!{});
+   |             ^    ^
+   |
+help: remove these parentheses
+   |
+LL -     let _ = (x!{});
+LL +     let _ = x!{};
+   |
+
+error: unnecessary parentheses around `let` scrutinee expression
+  --> $DIR/unused-parens-for-macro-call-with-brace.rs:22:22
+   |
+LL |     if let Some(_) = (x!{}) {};
+   |                      ^    ^
+   |
+help: remove these parentheses
+   |
+LL -     if let Some(_) = (x!{}) {};
+LL +     if let Some(_) = x!{} {};
+   |
+
+error: unnecessary parentheses around `let` scrutinee expression
+  --> $DIR/unused-parens-for-macro-call-with-brace.rs:26:25
+   |
+LL |     while let Some(_) = (x!{}) {};
+   |                         ^    ^
+   |
+help: remove these parentheses
+   |
+LL -     while let Some(_) = (x!{}) {};
+LL +     while let Some(_) = x!{} {};
+   |
+
+error: aborting due to 5 previous errors
+