Detect redundant always successful `assert_eq!`
What it does
Detect if assert_eq! always returns succeeds because the same expression is on the left and right side, such as with assert_eq!(a,a).
These type of cases can happen when refactoring and search'n'replacing code, for example we've recently saw a case of this recently:
assert_eq!(mem::size_of::<usize>(), mem::size_of::<usize>());
It would however be important that it only lints on the expressions being exactly identical, so if using a type alias in the above example that should not trigger this lint, example:
type MyType = usize;
assert_eq!(mem::size_of::<usize>(), mem::size_of::<MyType>());
Lint Name
redundant_assert
Category
pedantic
Advantage
Keeping an assert that has no effect is a code smell and negative value as can leave a false sense of safety in tests / coverage and is additional cognitive overhead without any positive effects.
Drawbacks
Likely none.
Probably not that common occurrence, but does happen.
Example
assert_eq!(mem::size_of::<usize>(), mem::size_of::<usize>());
Assert should simply be removed as it has no effect.
Mh, sounds kinda hard, because when there is any kind of mutability or randomness involved, we can still end up with identical expressions that evaluate to completely different things :/
assert_eq!(
rand::thread_rng().gen::<u8>(),
rand::thread_rng().gen::<u8>()
)
For sure if the expression use global mutable state it doesn't work, I was thinking of it primarily for const functions (though I should have added that in the lint description).
std::mem::size_of for example is a const fn. And that could be easier to detect and cover?
Mh, sounds kinda hard, because when there is any kind of mutability or randomness involved, we can still end up with identical expressions that evaluate to completely different things :/
assert_eq!( rand::thread_rng().gen::<u8>(), rand::thread_rng().gen::<u8>() )
when assert_eq between random elements wouldn't that be wrong regardless?
the lint should warn about identical literal in assert_eq! regardless of randomness? In case of const or randomness for opposite reasons still wouldn't make sense, although the lint would work only for assert_eq! and not for assert_ne!
@lucarlig In more complex cases of non-deterministic functions it might be useful to run the same function twice and assert that the result is the same. For example, testing that a function that internally memoizes some intermediate result gives the same output before and after memoization has kicked in.
I think this could be a useful lint cause Rust allows shadowing variables, and it's too easy to forget the right name (especially after refactoring). This is a bug I found in tests that led me to this issue:
let non_optional = NonOptional { vec: vec![1, 2, 3] };
let non_optional: NonOptional =
serde_json::from_str(&serde_json::to_string(&non_optional).unwrap()).unwrap();
assert_eq!(non_optional, non_optional);
Not sure why not make this lint work simply for all cases, when the left and right sides are the same, and leave other corner cases to be enabled/disabled as usual per line/file.
Makes sense @rustbot claim
i think some parts of this lints overlap with eq_op lint, does it make sense to implement it as separate lint or expand that?