I have a incomplete but serviceable understanding of the difference between dynamic and static dispatch. I know all types need to have a known size as far as how they are used. So indirection has to be used for types that are used as traits because different implementers can have different sizes. That's all well and good, but what does the following code do, if anything
trait Trait {}
struct A;
impl Trait for A {}
struct B(Trait); // valid no error
Yeah I get that struct B(Trait) can't be constructed, but it's valid syntax. Without indirection like Box or compile time monomorphization or a reference of some sort, what can this do?
trait Trait {
fn func() where Self: Sized {}
}
struct B;
impl Trait for B {}
fn main() {
B::func();
}
Depending on what version of rust you're using, that actually is an error
error[E0782]: trait objects must include the `dyn` keyword
but if you fix that, you're right that it is allowed.
The last field in a struct is allowed to not be Sized, which makes the struct itself not Sized. Currently this is sort of a half-baked feature, because there's no way to construct a type like that. So you have to make B generic and then coerce a reference[1] to B<A> into a reference to B<dyn Trait>.
trait Trait {}
struct A;
impl Trait for A {}
struct B<T: ?Sized>(T); // valid no error
fn check() {
let b = B(A);
let dyn_b = &b as &B<dyn Trait>;
}
The nomicon has a section on DSTs that elaborates a bit