What does a raw trait type do?

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();
}

Is that all?

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
  1. or other pointer-like type ↩ī¸Ž

3 Likes

@semicoleon beat me to it, but here's a slightly more fleshed-out example:

trait Trait {
    fn query(&self)->i32;
}

struct A;
impl Trait for A {
    fn query(&self)->i32 { 42 }
}

struct B<T:Trait+?Sized = dyn Trait>(T);

impl<T:Trait+?Sized> B<T> {
    fn query2(&self)->i32 { self.0.query()*2 }
}

fn f(b:&B) {
    dbg!(b.query2());
}

fn main() {
    let b = B(A);
    f(&b);
}
2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.