Why are trait bounds for auto trait Send
on trait implementations ignored? (Playground(1))
trait IsSend {
fn is_send(&self);
}
impl<T: Send> IsSend for T {
fn is_send(&self) {}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let i = std::rc::Rc::new(43);
i.is_send(); // (!!) no compiler error although Rc<...> is not Send
Ok(())
}
For example using a trait bound for a self defined trait (X) it works: (Playground(2))
trait X {}
trait IsSend {
fn is_send(&self);
}
impl<T: X> IsSend for T {
fn is_send(&self) {}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let i = std::rc::Rc::new(43);
i.is_send(); // (ok) compiler error as Rc<...> does not implement X
Ok(())
}
Even more confusing, using a trait bound on a function it works as expected: (Playground(3))
fn is_send<T: Send>(_s: &T) {}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let i = std::rc::Rc::new(43);
is_send(&i); // (ok) compiler as Rc<...> is not Send
Ok(())
}
It looks like the auto trait Send
(or auto traits in general) is treated specially. However, I have not found any documentation about this. Is this a bug or just my lack of understanding :-)?
Rc<i32>
may not implementIsSend
, buti32
does, and dot notation invokes auto-deref. – trentcl