I'm trying to better understand the effect of implicit Sized(ness) bounds when it comes to traits and their implementations and I'd like to double check if my reasoning is correct when it comes to the following case
trait Foo {
fn foo(&self);
}
// No conflicting implementation with this one...
impl Foo for str {
fn foo(&self) {
todo!()
}
}
//... But I get a conflicting implementation error if I uncomment this one
// impl Foo for &str {
// fn foo(&self) {
// todo!()
// }
// }
impl<T> Foo for T
{
fn foo(&self) {
todo!()
}
}
QUESTIONS:
-
Is it correct to call the
impl<T> Foo for T
a blanket implementation even if there are no explicit bounds on T? I mean, I thought a blanket implementation was saying: "implement this trait for all types satisfying these bounds", but there are no explicit bounds here... Maybe it's the implicitT: Sized
bound that makes it a blanket implementation proper? Or is my definition of blanket implementation wrong? -
Let's assume I can call it a blanket implementation: is it correct to think that this code compiles because the implicit
T: Sized
bound in such blanket implementation prevents it to conflict with theimpl Foo for str
given thatstr
is!Sized
? -
If 1 is correct then the fact that uncommenting the
impl Foo for &str
causes a compilation error can be explained by saying that&str: Sized
and so such implementation is already "covered" by the blanket one? -
How to reason about the fact that
Self
is implicitly?Sized
in the trait definition, but it "becomes"Sized
in the blanket implementation? Is it because whenever we are in a generic context, any type placeholderT
is always considered to beSized
?
I'm trying to ensure my mental model has no huge flaws here...
Thanks,
Andrea