Description
What it does
Consider the following (admittedly silly) code:
fn id<T: Copy + ?Sized>(t: &T) -> &T {
t
}
The author clearly meant for this method to work on unsized T
, but the Copy
bound implicitly implies Clone
, which implies Sized
, so the compiler will deduce that T
is Sized
. Right now, it compiles and passes clippy silently. Instead, clippy should warn that the ?Sized
anti-bound is useless, and suggest removing one of the two bounds.
Here's a silly-but-slightly-less-so example:
unsafe fn deref<T: Copy + ?Sized>(ptr: *const T) -> T {
*ptr
}
Here, someone might have this function without the ?Sized
anti-bound (Copy
is required to move out of the pointer), realize they want to call it with an unsized type, and modify it like so. (In my case, I was trying to construct an example of ?Sized
and pointer dereferencing, and ended up surprised for a few minutes that this compiled.)
A similar case is #1463, i.e. bounds where one implies the other, for example T: Copy + Clone
. That seems potentially less bad, because there's no issue with the code's intent; it's just an unnecessarily complex bound.
Lint Name
useless_anti_bound
Category
suspicious
Advantage
- Clearer intent
- Removes useless code
Drawbacks
None I can think of.
Example
fn id<T: Copy + ?Sized>(t: &T) -> &T {
t
}
Could be written as:
fn id<T: Copy>(t: &T) -> &T {
t
}