about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSamuel Tardieu <sam@rfc1149.net>2024-05-25 18:08:14 +0200
committerSamuel Tardieu <sam@rfc1149.net>2024-06-06 20:53:08 +0200
commit35b2aa99f3357a69d09f247ed5aff64cdd7765b1 (patch)
tree0ed9588409da7e3ccd940adfd7a9e7b08ee72299
parent1e23449678e4c986b609ed7a82ae6497e7b6ddd1 (diff)
downloadrust-35b2aa99f3357a69d09f247ed5aff64cdd7765b1.tar.gz
rust-35b2aa99f3357a69d09f247ed5aff64cdd7765b1.zip
Add required parentheses around method receiver
-rw-r--r--clippy_lints/src/needless_bool.rs13
-rw-r--r--tests/ui/needless_bool/fixable.fixed12
-rw-r--r--tests/ui/needless_bool/fixable.rs12
-rw-r--r--tests/ui/needless_bool/fixable.stderr20
4 files changed, 53 insertions, 4 deletions
diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs
index e1866eaa18a..9cb4fa41c73 100644
--- a/clippy_lints/src/needless_bool.rs
+++ b/clippy_lints/src/needless_bool.rs
@@ -6,8 +6,8 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{
-    higher, is_block_like, is_else_clause, is_expn_of, is_parent_stmt, peel_blocks, peel_blocks_with_stmt,
-    span_extract_comment, SpanlessEq,
+    get_parent_expr, higher, is_block_like, is_else_clause, is_expn_of, is_parent_stmt, is_receiver_of_method_call,
+    peel_blocks, peel_blocks_with_stmt, span_extract_comment, SpanlessEq,
 };
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
@@ -154,7 +154,10 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBool {
                     snip = snip.blockify();
                 }
 
-                if condition_needs_parentheses(cond) && is_parent_stmt(cx, e.hir_id) {
+                if (condition_needs_parentheses(cond) && is_parent_stmt(cx, e.hir_id))
+                    || is_receiver_of_method_call(cx, e)
+                    || is_as_argument(cx, e)
+                {
                     snip = snip.maybe_par();
                 }
 
@@ -442,3 +445,7 @@ fn fetch_assign<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<(&'tcx Expr<'tcx>, bool)
         None
     }
 }
+
+fn is_as_argument(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
+    matches!(get_parent_expr(cx, e).map(|e| e.kind), Some(ExprKind::Cast(_, _)))
+}
diff --git a/tests/ui/needless_bool/fixable.fixed b/tests/ui/needless_bool/fixable.fixed
index 3059de8f89c..ec63c4fd6a2 100644
--- a/tests/ui/needless_bool/fixable.fixed
+++ b/tests/ui/needless_bool/fixable.fixed
@@ -131,3 +131,15 @@ fn needless_bool_condition() -> bool {
 
     foo()
 }
+
+fn issue12846() {
+    let a = true;
+    let b = false;
+
+    // parentheses are needed here
+    let _x = (a && b).then(|| todo!());
+    let _x = (a && b) as u8;
+
+    // parentheses are not needed here
+    let _x = a.then(|| todo!());
+}
diff --git a/tests/ui/needless_bool/fixable.rs b/tests/ui/needless_bool/fixable.rs
index b2cbe86e223..8694aa71590 100644
--- a/tests/ui/needless_bool/fixable.rs
+++ b/tests/ui/needless_bool/fixable.rs
@@ -191,3 +191,15 @@ fn needless_bool_condition() -> bool {
 
     foo()
 }
+
+fn issue12846() {
+    let a = true;
+    let b = false;
+
+    // parentheses are needed here
+    let _x = if a && b { true } else { false }.then(|| todo!());
+    let _x = if a && b { true } else { false } as u8;
+
+    // parentheses are not needed here
+    let _x = if a { true } else { false }.then(|| todo!());
+}
diff --git a/tests/ui/needless_bool/fixable.stderr b/tests/ui/needless_bool/fixable.stderr
index 9746e931f50..99b5b998344 100644
--- a/tests/ui/needless_bool/fixable.stderr
+++ b/tests/ui/needless_bool/fixable.stderr
@@ -191,5 +191,23 @@ error: this if-then-else expression returns a bool literal
 LL |         if unsafe { no(4) } & 1 != 0 { true } else { false }
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(unsafe { no(4) } & 1 != 0)`
 
-error: aborting due to 21 previous errors
+error: this if-then-else expression returns a bool literal
+  --> tests/ui/needless_bool/fixable.rs:200:14
+   |
+LL |     let _x = if a && b { true } else { false }.then(|| todo!());
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(a && b)`
+
+error: this if-then-else expression returns a bool literal
+  --> tests/ui/needless_bool/fixable.rs:201:14
+   |
+LL |     let _x = if a && b { true } else { false } as u8;
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(a && b)`
+
+error: this if-then-else expression returns a bool literal
+  --> tests/ui/needless_bool/fixable.rs:204:14
+   |
+LL |     let _x = if a { true } else { false }.then(|| todo!());
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `a`
+
+error: aborting due to 24 previous errors