Slices are Sized Right? @BoxyUwU @WaffleLapkin

Note: The T: Sized bound made explicit on trait TraitB is 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.