-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
Description
This code:
#![warn(clippy::bool_comparison)]
#![allow(unused)]
fn func() -> bool {
true
}
macro_rules! m {
($func:ident) => {
$func()
};
}
fn foo(x: bool) -> bool {
x > m!(func)
}
Caused the following diagnostics:
warning: order comparisons between booleans can be simplified
--> src/lib.rs:15:5
|
15 | x > m!(func)
| ^^^^^^^^^^^^ help: try simplifying it as shown: `x & !$func()`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#bool_comparison
As you can already see, the output won't compile, because, instead of copying m!(func)
into the suggestion verbatim, the lint inserts the macro contents (and does even that incorrectly, since the $
remains for some reason).
This issue was previously noticed for expressions of the form !x == y
/x == !y
, and fixed, in #11991. But that PR missed the cases x > y
and x < y
.
Fixing those is a bit complicated:
-
The lint currently has a
check_comparison
function, which looks at whether the sides of a binary expressions are literals. It takes ano_literal
closure for the case where there aren't any. -
For the binops
!=
and==
, the closure isNone
, i.e. no suggestion happens (but there's a catch, see below) -
For
>
and<
on the other hand, the closure is|l: Sugg, r: Sugg| l.bit_and(&(!r))
and|l: Sugg, r: Sugg| (!l).bit_and(&r)
, respectively, so e.g.x > y
turns intox & !y
. -
There is one expection to (2): when one of the sides of
==
is!a
, the lint turns!x == y
intox != y
andx == !y
intox != y
.- The PR modified exactly this phase -- the
snippet
for eachside
used to be generated from justside.span
, but the PR turned that intoside.span.source_callsite()
- The PR modified exactly this phase -- the
-
So I guess one way to solve this would be to:
- change the
<
/>
closures to operate onsnippet
s as well - make them construct
{x} & !{y}
manually, usingformat!
One downside of this is that we lose all the precedence- and paren-handling logic of
Span::bit_and
. Though one could argue that the current implementation of (4) suffers from the same problem. - change the
One more complication is that I'm actually going to remove the special-handling that is (4) in an upcoming PR -- see it for the motivation^^
Version
playground:
- stable 1.89.0
- nightly 1.91.0 (2025-08-13)
Additional Labels
@rustbot label I-suggestion-causes-error