Skip to content

Commit d553ebe

Browse files
committed
Auto merge of rust-lang#12851 - samueltardieu:issue12846, r=y21
Add required parentheses around method receiver Fix rust-lang#12846 changelog: [`needless_bool`]: Add missing parentheses around method receiver
2 parents 1e40764 + 35b2aa9 commit d553ebe

File tree

6 files changed

+65
-15
lines changed

6 files changed

+65
-15
lines changed

clippy_lints/src/methods/search_is_some.rs

+1-11
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
22
use clippy_utils::source::{snippet, snippet_with_applicability};
33
use clippy_utils::sugg::deref_closure_args;
44
use clippy_utils::ty::is_type_lang_item;
5-
use clippy_utils::{get_parent_expr, is_trait_method, strip_pat_refs};
5+
use clippy_utils::{is_receiver_of_method_call, is_trait_method, strip_pat_refs};
66
use hir::ExprKind;
77
use rustc_errors::Applicability;
88
use rustc_hir as hir;
@@ -156,13 +156,3 @@ pub(super) fn check<'tcx>(
156156
}
157157
}
158158
}
159-
160-
fn is_receiver_of_method_call(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
161-
if let Some(parent_expr) = get_parent_expr(cx, expr)
162-
&& let ExprKind::MethodCall(_, receiver, ..) = parent_expr.kind
163-
&& receiver.hir_id == expr.hir_id
164-
{
165-
return true;
166-
}
167-
false
168-
}

clippy_lints/src/needless_bool.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
66
use clippy_utils::source::snippet_with_applicability;
77
use clippy_utils::sugg::Sugg;
88
use clippy_utils::{
9-
higher, is_block_like, is_else_clause, is_expn_of, is_parent_stmt, peel_blocks, peel_blocks_with_stmt,
10-
span_extract_comment, SpanlessEq,
9+
get_parent_expr, higher, is_block_like, is_else_clause, is_expn_of, is_parent_stmt, is_receiver_of_method_call,
10+
peel_blocks, peel_blocks_with_stmt, span_extract_comment, SpanlessEq,
1111
};
1212
use rustc_ast::ast::LitKind;
1313
use rustc_errors::Applicability;
@@ -154,7 +154,10 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBool {
154154
snip = snip.blockify();
155155
}
156156

157-
if condition_needs_parentheses(cond) && is_parent_stmt(cx, e.hir_id) {
157+
if (condition_needs_parentheses(cond) && is_parent_stmt(cx, e.hir_id))
158+
|| is_receiver_of_method_call(cx, e)
159+
|| is_as_argument(cx, e)
160+
{
158161
snip = snip.maybe_par();
159162
}
160163

@@ -442,3 +445,7 @@ fn fetch_assign<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<(&'tcx Expr<'tcx>, bool)
442445
None
443446
}
444447
}
448+
449+
fn is_as_argument(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
450+
matches!(get_parent_expr(cx, e).map(|e| e.kind), Some(ExprKind::Cast(_, _)))
451+
}

clippy_utils/src/lib.rs

+11
Original file line numberDiff line numberDiff line change
@@ -3401,3 +3401,14 @@ pub fn binary_expr_needs_parentheses(expr: &Expr<'_>) -> bool {
34013401

34023402
contains_block(expr, false)
34033403
}
3404+
3405+
/// Returns true if the specified expression is in a receiver position.
3406+
pub fn is_receiver_of_method_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
3407+
if let Some(parent_expr) = get_parent_expr(cx, expr)
3408+
&& let ExprKind::MethodCall(_, receiver, ..) = parent_expr.kind
3409+
&& receiver.hir_id == expr.hir_id
3410+
{
3411+
return true;
3412+
}
3413+
false
3414+
}

tests/ui/needless_bool/fixable.fixed

+12
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,15 @@ fn needless_bool_condition() -> bool {
131131

132132
foo()
133133
}
134+
135+
fn issue12846() {
136+
let a = true;
137+
let b = false;
138+
139+
// parentheses are needed here
140+
let _x = (a && b).then(|| todo!());
141+
let _x = (a && b) as u8;
142+
143+
// parentheses are not needed here
144+
let _x = a.then(|| todo!());
145+
}

tests/ui/needless_bool/fixable.rs

+12
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,15 @@ fn needless_bool_condition() -> bool {
191191

192192
foo()
193193
}
194+
195+
fn issue12846() {
196+
let a = true;
197+
let b = false;
198+
199+
// parentheses are needed here
200+
let _x = if a && b { true } else { false }.then(|| todo!());
201+
let _x = if a && b { true } else { false } as u8;
202+
203+
// parentheses are not needed here
204+
let _x = if a { true } else { false }.then(|| todo!());
205+
}

tests/ui/needless_bool/fixable.stderr

+19-1
Original file line numberDiff line numberDiff line change
@@ -191,5 +191,23 @@ error: this if-then-else expression returns a bool literal
191191
LL | if unsafe { no(4) } & 1 != 0 { true } else { false }
192192
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(unsafe { no(4) } & 1 != 0)`
193193

194-
error: aborting due to 21 previous errors
194+
error: this if-then-else expression returns a bool literal
195+
--> tests/ui/needless_bool/fixable.rs:200:14
196+
|
197+
LL | let _x = if a && b { true } else { false }.then(|| todo!());
198+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(a && b)`
199+
200+
error: this if-then-else expression returns a bool literal
201+
--> tests/ui/needless_bool/fixable.rs:201:14
202+
|
203+
LL | let _x = if a && b { true } else { false } as u8;
204+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(a && b)`
205+
206+
error: this if-then-else expression returns a bool literal
207+
--> tests/ui/needless_bool/fixable.rs:204:14
208+
|
209+
LL | let _x = if a { true } else { false }.then(|| todo!());
210+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `a`
211+
212+
error: aborting due to 24 previous errors
195213

0 commit comments

Comments
 (0)