-
Notifications
You must be signed in to change notification settings - Fork 1.7k
bool_assert_comparison false positive when one side is non-bool with PartialEq<bool> impl #7548
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hi @Manishearth! I would like to try fixing this issue if you don't mind. I'm absolutely new to Rust community. I've seen that currently this lint is only checking if the assert parameters are boolean literals. My idea here is the following:
What do you think about it? |
Welcome to the project @xordi, for lints that work with macros, it's usually good to understand how they work. For that, you can open the Rust playground and see the macro expansion using In this case, the difference comes from the way the values are checked. Based on this, I would suggest to check for the If this sounds interesting to you, and you want to try your hand on it, feel free to claim the issue via |
@rustbot claim |
Thanks for the explanation @xFrednet. Let's say we have the following code, with an enum type that implements use std::ops::Not;
#[derive(Debug)]
enum Test {
Bool(bool),
Number(u32)
}
impl PartialEq<bool> for Test {
fn eq(&self, other: &bool) -> bool {
match *self {
Test::Bool(b) => b == *other,
_ => false
}
}
}
impl Not for Test {
type Output = Self;
fn not(self) -> Self::Output {
match self {
Test::Bool(b) => Test::Bool(!b),
Test::Number(0) => Test::Number(1),
Test::Number(_) => Test::Number(0),
}
}
}
fn main() {
let t = Test::Bool(true);
// currently clippy suggests that this should be replaced
// with assert!(...)
assert_eq!(t, true);
// assert! expects a boolean expression, so this
// doesn't compile
assert!(t);
} It looks wrong when clippy suggests a rewrite that leads into a compilation error like in this case. So maybe just checking for the |
You're welcome! That's a very good test 👍 Rust allows operators to define their output type. The given example defines the output type as
I'm guessing that you're referring here to checking the actual type of the expression? That would also prevent some false positives, like in this case, but could also lead to false negatives. For instance, if |
Lint name: bool_assert_comparison
When testing
serde_json::Value
values, or more generally more-complex-than-bool types that implementPartialEq<bool>
,assert_eq!
testing should not be linted against.Example
These trigger bool_assert_comparison lint
However, these aren't trivially fixable with
assert!(..)
. Moreover, converting to a bool for testing is worse code as it provides less info in a test failure scenario. For example, running the example code tells us not only that the 2nd assert fails, but exactly what the actual value was.A workaround like
assert_eq!(val["baz"].as_bool(), Some(false))
would make this test code worse, and does not seem to be the intention of this lint.Meta
cargo clippy -V
:clippy 0.1.56 (ad981d5 2021-08-08)
rustc -Vv
:The text was updated successfully, but these errors were encountered: