about summary refs log tree commit diff
diff options
context:
space:
mode:
authoryukang <moorekang@gmail.com>2025-06-29 11:40:59 +0800
committeryukang <moorekang@gmail.com>2025-07-10 09:25:56 +0800
commit93db9e7ee01d61cb97b4f7b3d61903477910cae2 (patch)
tree1769ebc661756b170deb03ce2bc48c9616a89d9f
parente43d139a82620a268d3828a73e12a8679339e8f8 (diff)
downloadrust-93db9e7ee01d61cb97b4f7b3d61903477910cae2.tar.gz
rust-93db9e7ee01d61cb97b4f7b3d61903477910cae2.zip
Remove uncessary parens in closure body with unused lint
-rw-r--r--compiler/rustc_errors/src/emitter.rs2
-rw-r--r--compiler/rustc_lint/src/unused.rs10
-rw-r--r--compiler/rustc_parse/src/parser/item.rs2
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs3
-rw-r--r--library/core/src/unicode/unicode_data.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_async.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/ty/mod.rs4
-rw-r--r--src/tools/compiletest/src/runtest.rs6
-rw-r--r--src/tools/test-float-parse/src/lib.rs2
-rw-r--r--src/tools/unicode-table-generator/src/range_search.rs2
-rw-r--r--tests/ui/async-await/issues/issue-54752-async-block.rs1
-rw-r--r--tests/ui/async-await/issues/issue-54752-async-block.stderr15
-rw-r--r--tests/ui/lint/unused/closure-body-issue-136741.fixed36
-rw-r--r--tests/ui/lint/unused/closure-body-issue-136741.rs38
-rw-r--r--tests/ui/lint/unused/closure-body-issue-136741.stderr62
15 files changed, 160 insertions, 27 deletions
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 2f398cea926..510f37f37e2 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -3526,7 +3526,7 @@ pub fn is_case_difference(sm: &SourceMap, suggested: &str, sp: Span) -> bool {
     // All the chars that differ in capitalization are confusable (above):
     let confusable = iter::zip(found.chars(), suggested.chars())
         .filter(|(f, s)| f != s)
-        .all(|(f, s)| (ascii_confusables.contains(&f) || ascii_confusables.contains(&s)));
+        .all(|(f, s)| ascii_confusables.contains(&f) || ascii_confusables.contains(&s));
     confusable && found.to_lowercase() == suggested.to_lowercase()
             // FIXME: We sometimes suggest the same thing we already have, which is a
             //        bug, but be defensive against that here.
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index d3942a1c816..a9eb1739f7f 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -1,7 +1,7 @@
 use std::iter;
 
 use rustc_ast::util::{classify, parser};
-use rustc_ast::{self as ast, ExprKind, HasAttrs as _, StmtKind};
+use rustc_ast::{self as ast, ExprKind, FnRetTy, HasAttrs as _, StmtKind};
 use rustc_attr_data_structures::{AttributeKind, find_attr};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{MultiSpan, pluralize};
@@ -599,6 +599,7 @@ enum UnusedDelimsCtx {
     AnonConst,
     MatchArmExpr,
     IndexExpr,
+    ClosureBody,
 }
 
 impl From<UnusedDelimsCtx> for &'static str {
@@ -620,6 +621,7 @@ impl From<UnusedDelimsCtx> for &'static str {
             UnusedDelimsCtx::ArrayLenExpr | UnusedDelimsCtx::AnonConst => "const expression",
             UnusedDelimsCtx::MatchArmExpr => "match arm expression",
             UnusedDelimsCtx::IndexExpr => "index expression",
+            UnusedDelimsCtx::ClosureBody => "closure body",
         }
     }
 }
@@ -919,6 +921,11 @@ trait UnusedDelimLint {
                 let (args_to_check, ctx) = match *call_or_other {
                     Call(_, ref args) => (&args[..], UnusedDelimsCtx::FunctionArg),
                     MethodCall(ref call) => (&call.args[..], UnusedDelimsCtx::MethodArg),
+                    Closure(ref closure)
+                        if matches!(closure.fn_decl.output, FnRetTy::Default(_)) =>
+                    {
+                        (&[closure.body.clone()][..], UnusedDelimsCtx::ClosureBody)
+                    }
                     // actual catch-all arm
                     _ => {
                         return;
@@ -1508,6 +1515,7 @@ impl UnusedDelimLint for UnusedBraces {
                             && (ctx != UnusedDelimsCtx::AnonConst
                                 || (matches!(expr.kind, ast::ExprKind::Lit(_))
                                     && !expr.span.from_expansion()))
+                            && ctx != UnusedDelimsCtx::ClosureBody
                             && !cx.sess().source_map().is_multiline(value.span)
                             && value.attrs.is_empty()
                             && !value.span.from_expansion()
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 9ed7124a11c..d6cc98d505c 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2206,7 +2206,7 @@ impl<'a> Parser<'a> {
 
             if self.look_ahead(1, |t| *t == token::Bang) && self.look_ahead(2, |t| t.is_ident()) {
                 return IsMacroRulesItem::Yes { has_bang: true };
-            } else if self.look_ahead(1, |t| (t.is_ident())) {
+            } else if self.look_ahead(1, |t| t.is_ident()) {
                 // macro_rules foo
                 self.dcx().emit_err(errors::MacroRulesMissingBang {
                     span: macro_rules_span,
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index e015eb7a636..8114021510e 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -328,8 +328,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                 let module_did = mod_prefix.as_ref().and_then(Res::mod_def_id);
 
                 let mod_prefix =
-                    mod_prefix.map_or_else(String::new, |res| (format!("{} ", res.descr())));
-
+                    mod_prefix.map_or_else(String::new, |res| format!("{} ", res.descr()));
                 (mod_prefix, format!("`{}`", Segment::names_to_string(mod_path)), module_did, None)
             };
 
diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs
index 25b9c6e0e0e..b57234bbee9 100644
--- a/library/core/src/unicode/unicode_data.rs
+++ b/library/core/src/unicode/unicode_data.rs
@@ -82,7 +82,7 @@ unsafe fn skip_search<const SOR: usize, const OFFSETS: usize>(
     let needle = needle as u32;
 
     let last_idx =
-        match short_offset_runs.binary_search_by_key(&(needle << 11), |header| (header.0 << 11)) {
+        match short_offset_runs.binary_search_by_key(&(needle << 11), |header| header.0 << 11) {
             Ok(idx) => idx + 1,
             Err(idx) => idx,
         };
diff --git a/src/tools/clippy/clippy_lints/src/unused_async.rs b/src/tools/clippy/clippy_lints/src/unused_async.rs
index 8ceaa3dc58e..e67afc7f5a8 100644
--- a/src/tools/clippy/clippy_lints/src/unused_async.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_async.rs
@@ -169,7 +169,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync {
         let iter = self
             .unused_async_fns
             .iter()
-            .filter(|UnusedAsyncFn { def_id, .. }| (!self.async_fns_as_value.contains(def_id)));
+            .filter(|UnusedAsyncFn { def_id, .. }| !self.async_fns_as_value.contains(def_id));
 
         for fun in iter {
             span_lint_hir_and_then(
diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs
index bffbcf073ab..fe208c032f4 100644
--- a/src/tools/clippy/clippy_utils/src/ty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs
@@ -889,7 +889,7 @@ impl AdtVariantInfo {
                     .enumerate()
                     .map(|(i, f)| (i, approx_ty_size(cx, f.ty(cx.tcx, subst))))
                     .collect::<Vec<_>>();
-                fields_size.sort_by(|(_, a_size), (_, b_size)| (a_size.cmp(b_size)));
+                fields_size.sort_by(|(_, a_size), (_, b_size)| a_size.cmp(b_size));
 
                 Self {
                     ind: i,
@@ -898,7 +898,7 @@ impl AdtVariantInfo {
                 }
             })
             .collect::<Vec<_>>();
-        variants_size.sort_by(|a, b| (b.size.cmp(&a.size)));
+        variants_size.sort_by(|a, b| b.size.cmp(&a.size));
         variants_size
     }
 }
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 3e879e0e4bb..933a32392bd 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1777,6 +1777,12 @@ impl<'test> TestCx<'test> {
         // Allow tests to use internal features.
         rustc.args(&["-A", "internal_features"]);
 
+        // Allow tests to have unused parens and braces.
+        // Add #![deny(unused_parens, unused_braces)] to the test file if you want to
+        // test that these lints are working.
+        rustc.args(&["-A", "unused_parens"]);
+        rustc.args(&["-A", "unused_braces"]);
+
         if self.props.force_host {
             self.maybe_add_external_args(&mut rustc, &self.config.host_rustcflags);
             if !is_rustdoc {
diff --git a/src/tools/test-float-parse/src/lib.rs b/src/tools/test-float-parse/src/lib.rs
index 0bd4878f9a6..1321a3c3354 100644
--- a/src/tools/test-float-parse/src/lib.rs
+++ b/src/tools/test-float-parse/src/lib.rs
@@ -340,7 +340,7 @@ fn launch_tests(tests: &mut [TestInfo], cfg: &Config) -> Duration {
     for test in tests.iter_mut() {
         test.progress = Some(ui::Progress::new(test, &mut all_progress_bars));
         ui::set_panic_hook(&all_progress_bars);
-        ((test.launch)(test, cfg));
+        (test.launch)(test, cfg);
     }
 
     start.elapsed()
diff --git a/src/tools/unicode-table-generator/src/range_search.rs b/src/tools/unicode-table-generator/src/range_search.rs
index 02f9cf16d4d..4d1dd9b423b 100644
--- a/src/tools/unicode-table-generator/src/range_search.rs
+++ b/src/tools/unicode-table-generator/src/range_search.rs
@@ -80,7 +80,7 @@ unsafe fn skip_search<const SOR: usize, const OFFSETS: usize>(
     let needle = needle as u32;
 
     let last_idx =
-        match short_offset_runs.binary_search_by_key(&(needle << 11), |header| (header.0 << 11)) {
+        match short_offset_runs.binary_search_by_key(&(needle << 11), |header| header.0 << 11) {
             Ok(idx) => idx + 1,
             Err(idx) => idx,
         };
diff --git a/tests/ui/async-await/issues/issue-54752-async-block.rs b/tests/ui/async-await/issues/issue-54752-async-block.rs
index 452b6794bee..164c1885da1 100644
--- a/tests/ui/async-await/issues/issue-54752-async-block.rs
+++ b/tests/ui/async-await/issues/issue-54752-async-block.rs
@@ -4,4 +4,3 @@
 //@ pp-exact
 
 fn main() { let _a = (async { }); }
-//~^ WARNING unnecessary parentheses around assigned value
diff --git a/tests/ui/async-await/issues/issue-54752-async-block.stderr b/tests/ui/async-await/issues/issue-54752-async-block.stderr
deleted file mode 100644
index 8cc849dd985..00000000000
--- a/tests/ui/async-await/issues/issue-54752-async-block.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-warning: unnecessary parentheses around assigned value
-  --> $DIR/issue-54752-async-block.rs:6:22
-   |
-LL | fn main() { let _a = (async { }); }
-   |                      ^         ^
-   |
-   = note: `#[warn(unused_parens)]` on by default
-help: remove these parentheses
-   |
-LL - fn main() { let _a = (async { }); }
-LL + fn main() { let _a = async { }; }
-   |
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/lint/unused/closure-body-issue-136741.fixed b/tests/ui/lint/unused/closure-body-issue-136741.fixed
new file mode 100644
index 00000000000..2ded52544b9
--- /dev/null
+++ b/tests/ui/lint/unused/closure-body-issue-136741.fixed
@@ -0,0 +1,36 @@
+//@ run-rustfix
+// ignore-tidy-linelength
+#![deny(unused_parens)]
+#![deny(unused_braces)]
+
+fn long_expr_that_does_not_require_braces_long_expr_that_does_not_require_braces_long_expr_that_does_not_require_braces()
+{}
+
+fn func(f: impl FnOnce()) {
+    f()
+}
+
+pub fn main() {
+    let _closure = |x: i32, y: i32| { x * (x + (y * 2)) };
+    let _ = || 0 == 0; //~ ERROR unnecessary parentheses around closure body
+    let _ = (0..).find(|n| n % 2 == 0); //~ ERROR unnecessary parentheses around closure body
+    let _ = (0..).find(|n| {n % 2 == 0});
+
+    // multiple lines of code will not lint with braces
+    let _ = (0..).find(|n| {
+        n % 2 == 0
+    });
+
+    // multiple lines of code will lint with parentheses
+    let _ = (0..).find(|n| n % 2 == 0);
+
+    let _ = || {
+        _ = 0;
+        0 == 0 //~ ERROR unnecessary parentheses around block return value
+    };
+
+    // long expressions will not lint with braces
+    func(|| {
+        long_expr_that_does_not_require_braces_long_expr_that_does_not_require_braces_long_expr_that_does_not_require_braces()
+    })
+}
diff --git a/tests/ui/lint/unused/closure-body-issue-136741.rs b/tests/ui/lint/unused/closure-body-issue-136741.rs
new file mode 100644
index 00000000000..4eac981ec2e
--- /dev/null
+++ b/tests/ui/lint/unused/closure-body-issue-136741.rs
@@ -0,0 +1,38 @@
+//@ run-rustfix
+// ignore-tidy-linelength
+#![deny(unused_parens)]
+#![deny(unused_braces)]
+
+fn long_expr_that_does_not_require_braces_long_expr_that_does_not_require_braces_long_expr_that_does_not_require_braces()
+{}
+
+fn func(f: impl FnOnce()) {
+    f()
+}
+
+pub fn main() {
+    let _closure = |x: i32, y: i32| { x * (x + (y * 2)) };
+    let _ = || (0 == 0); //~ ERROR unnecessary parentheses around closure body
+    let _ = (0..).find(|n| (n % 2 == 0)); //~ ERROR unnecessary parentheses around closure body
+    let _ = (0..).find(|n| {n % 2 == 0});
+
+    // multiple lines of code will not lint with braces
+    let _ = (0..).find(|n| {
+        n % 2 == 0
+    });
+
+    // multiple lines of code will lint with parentheses
+    let _ = (0..).find(|n| ( //~ ERROR unnecessary parentheses around closure body
+        n % 2 == 0
+    ));
+
+    let _ = || {
+        _ = 0;
+        (0 == 0) //~ ERROR unnecessary parentheses around block return value
+    };
+
+    // long expressions will not lint with braces
+    func(|| {
+        long_expr_that_does_not_require_braces_long_expr_that_does_not_require_braces_long_expr_that_does_not_require_braces()
+    })
+}
diff --git a/tests/ui/lint/unused/closure-body-issue-136741.stderr b/tests/ui/lint/unused/closure-body-issue-136741.stderr
new file mode 100644
index 00000000000..2ea872c08c7
--- /dev/null
+++ b/tests/ui/lint/unused/closure-body-issue-136741.stderr
@@ -0,0 +1,62 @@
+error: unnecessary parentheses around closure body
+  --> $DIR/closure-body-issue-136741.rs:15:16
+   |
+LL |     let _ = || (0 == 0);
+   |                ^      ^
+   |
+note: the lint level is defined here
+  --> $DIR/closure-body-issue-136741.rs:3:9
+   |
+LL | #![deny(unused_parens)]
+   |         ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     let _ = || (0 == 0);
+LL +     let _ = || 0 == 0;
+   |
+
+error: unnecessary parentheses around closure body
+  --> $DIR/closure-body-issue-136741.rs:16:28
+   |
+LL |     let _ = (0..).find(|n| (n % 2 == 0));
+   |                            ^          ^
+   |
+help: remove these parentheses
+   |
+LL -     let _ = (0..).find(|n| (n % 2 == 0));
+LL +     let _ = (0..).find(|n| n % 2 == 0);
+   |
+
+error: unnecessary parentheses around closure body
+  --> $DIR/closure-body-issue-136741.rs:25:28
+   |
+LL |        let _ = (0..).find(|n| (
+   |  _____________________________^
+LL | |          n % 2 == 0
+   | | ________^__________^
+   | ||________|
+   |  |
+LL |  |     ));
+   |  |_____^
+   |
+help: remove these parentheses
+   |
+LL -     let _ = (0..).find(|n| (
+LL -         n % 2 == 0
+LL +     let _ = (0..).find(|n| n % 2 == 0);
+   |
+
+error: unnecessary parentheses around block return value
+  --> $DIR/closure-body-issue-136741.rs:31:9
+   |
+LL |         (0 == 0)
+   |         ^      ^
+   |
+help: remove these parentheses
+   |
+LL -         (0 == 0)
+LL +         0 == 0
+   |
+
+error: aborting due to 4 previous errors
+