Slices are Sized Right? @BoxyUwU @WaffleLapkin
Note: The
T: Sizedbound made explicit ontrait TraitBis unnecessary. It is present solely to draw attention to the (implicit) bound.
trait TraitA {}
trait TraitB<T: Sized> {}
impl TraitA for &dyn TraitB<[u8]> {}
trait MyDefault {
fn default() -> Self;
}
impl<T: TraitA> MyDefault for T {
fn default() -> T {
todo!("not important for the example")
}
}
fn main() {
<&dyn TraitB<[u8]> as MyDefault>::default();
}
Solution
thread 'main' (???) panicked at examples/trait_solver_3.rs:12:9:
not yet implemented: not important for the example
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
When the compiler checks that a type is well formed (i.e. all of its where clauses hold), it skips checking the where clauses of the Trait of a trait object.
This means that when checking dyn Trait<T> is well formed, we don't require any of the bounds involving T hold. For example T: Sized in this question's TraitB trait object.
However, note that the compiler still enforces the generic arguments are themselves well formed. For example dyn TraitB<Vec<[u8]>> would be rejected by the compiler.
This questions's example compiling successfully is certainly a bug in the compiler, however it is likely not a soundness bug. The trait bounds on the trait of a trait object are actually upheld when coercing a value to a trait object, rather than when naming the trait object type.