There is no specialization in stable Rust yet, so this does not work:
trait X {}
impl<T> X for T {}
impl X for u32 {} // conflicting implementation
No surprises there: X
is implemented for any type T
and we can't implement it again for u32
.
Surprisingly, the following snippet compiles successfuly:
use std::fmt::Display;
pub trait Show {}
impl<T: Display> Show for T {}
impl Show for str {}
// These impls would cause "conflicting implementation" errors:
// impl<'a> Show for &'a str
// impl Show for String
fn main() {}
I would not expect this code to compile because Display
is implemented for str
, so the generic impl should implement Show
for str
and conflict with the specific impl.
Why does impl Show for str
not conflict with impl<T: Display> Show for T
?
The bound <T: Display>
implicitly assumes T
must be a Sized type. However str
is unsized. Therefore the two impls are not in conflict with each other.
If you need to cover unsized types like str
as well, you need to relax the Sized requirement by adding T: ?Sized
:
impl<T: Display + ?Sized> Show for T {}
// ^~~~~~~~
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With