Reputation: 9521
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
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