Some Name
Some Name

Reputation: 9521

Why is Sized required when using Self as a type parameter?

I'm playing around with traits and found that Sized is required when using Self as a type parameter:

trait Foo: Sized { // does not compile without Sized
    type Bar: Baz<F = Self>; 
    type Quiz: Qux<Self>
}

trait Baz {
    type F: Foo;
}

trait Qux<F: Foo> {}

Why does is matter to be Sized for Self? Why is it required to be specified explicitly and what's wrong with not Sized type in this situation?

Upvotes: 0

Views: 80

Answers (1)

Freyja
Freyja

Reputation: 40804

For type parameters and associated types, there's an implicit Sized trait bound that is set by default. So these are equivalent:

trait Baz {
    type F: Foo;
}

trait Qux<F: Foo> { }
trait Baz {
    type F: Foo + Sized;
}

trait Qux<F: Foo + Sized> { }

For both traits, F is required to be sized by default. So when you try to use them in the Foo trait, this means that Foo needs to be sized as well.

To allow unsized types, explicitly add the ?Sized trait bound to opt out of the default behavior:

trait Baz {
    type F: Foo + ?Sized;
}

trait Qux<F: Foo + ?Sized> { }

Which allows this to compile without needing to be Sized:

trait Foo {
    type Bar: Baz<F = Self>; 
    type Quiz: Qux<Self>;
}

Upvotes: 1

Related Questions