Skip to content

Commit 2202493

Browse files
committed
Auto merge of #12626 - folkertdev:incorrect-boolean-simplification, r=blyxyas
fix incorrect suggestion for `!(a as type >= b)` fixes #12625 The expression `!(a as type >= b)` got simplified to `a as type < b`, but because of rust's parsing rules that `<` is interpreted as a start of generic arguments for `type`. This is fixed by recognizing this case and adding extra parens around the left-hand side of the comparison. changelog: [`nonminimal_bool`]: fix incorrect suggestion for `!(a as type >= b)`
2 parents 1c9e965 + 6a2cb33 commit 2202493

File tree

4 files changed

+47
-6
lines changed

4 files changed

+47
-6
lines changed

clippy_lints/src/booleans.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -346,11 +346,18 @@ fn simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
346346
_ => None,
347347
}
348348
.and_then(|op| {
349-
Some(format!(
350-
"{}{op}{}",
351-
snippet_opt(cx, lhs.span)?,
352-
snippet_opt(cx, rhs.span)?
353-
))
349+
let lhs_snippet = snippet_opt(cx, lhs.span)?;
350+
let rhs_snippet = snippet_opt(cx, rhs.span)?;
351+
352+
if !(lhs_snippet.starts_with('(') && lhs_snippet.ends_with(')')) {
353+
if let (ExprKind::Cast(..), BinOpKind::Ge) = (&lhs.kind, binop.node) {
354+
// e.g. `(a as u64) < b`. Without the parens the `<` is
355+
// interpreted as a start of generic arguments for `u64`
356+
return Some(format!("({lhs_snippet}){op}{rhs_snippet}"));
357+
}
358+
}
359+
360+
Some(format!("{lhs_snippet}{op}{rhs_snippet}"))
354361
})
355362
},
356363
ExprKind::MethodCall(path, receiver, [], _) => {

tests/ui/nonminimal_bool_methods.fixed

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,12 @@ fn dont_warn_for_negated_partial_ord_comparison() {
109109
let _ = !(a >= b);
110110
}
111111

112+
fn issue_12625() {
113+
let a = 0;
114+
let b = 0;
115+
if (a as u64) < b {} //~ ERROR: this boolean expression can be simplified
116+
if (a as u64) < b {} //~ ERROR: this boolean expression can be simplified
117+
if a as u64 > b {} //~ ERROR: this boolean expression can be simplified
118+
}
119+
112120
fn main() {}

tests/ui/nonminimal_bool_methods.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,12 @@ fn dont_warn_for_negated_partial_ord_comparison() {
109109
let _ = !(a >= b);
110110
}
111111

112+
fn issue_12625() {
113+
let a = 0;
114+
let b = 0;
115+
if !(a as u64 >= b) {} //~ ERROR: this boolean expression can be simplified
116+
if !((a as u64) >= b) {} //~ ERROR: this boolean expression can be simplified
117+
if !(a as u64 <= b) {} //~ ERROR: this boolean expression can be simplified
118+
}
119+
112120
fn main() {}

tests/ui/nonminimal_bool_methods.stderr

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,23 @@ error: this boolean expression can be simplified
7979
LL | if !res.is_none() {}
8080
| ^^^^^^^^^^^^^^ help: try: `res.is_some()`
8181

82-
error: aborting due to 13 previous errors
82+
error: this boolean expression can be simplified
83+
--> tests/ui/nonminimal_bool_methods.rs:115:8
84+
|
85+
LL | if !(a as u64 >= b) {}
86+
| ^^^^^^^^^^^^^^^^ help: try: `(a as u64) < b`
87+
88+
error: this boolean expression can be simplified
89+
--> tests/ui/nonminimal_bool_methods.rs:116:8
90+
|
91+
LL | if !((a as u64) >= b) {}
92+
| ^^^^^^^^^^^^^^^^^^ help: try: `(a as u64) < b`
93+
94+
error: this boolean expression can be simplified
95+
--> tests/ui/nonminimal_bool_methods.rs:117:8
96+
|
97+
LL | if !(a as u64 <= b) {}
98+
| ^^^^^^^^^^^^^^^^ help: try: `a as u64 > b`
99+
100+
error: aborting due to 16 previous errors
83101

0 commit comments

Comments
 (0)