I have this code (playground):
trait NodeLike: Sized {}
fn main() {
let s: Box = panic!();
}
Which does not compile:
Having Self: ?Sized
on the trait type itself is a required property for a trait object, i.e. for 'object safety', even though you can have an impl
on a Self: ?Sized
trait with a Sized
type. Hence confusion.
It's a drawback that was decided upon in RFC 255 which deals with object safety (warning: obsolete Rust syntax).
It's a long read, but one of the alternatives was to determine 'object safety' by only analyzing the methods of the trait. It is admitted in the RFC that having this restriction will make some code that could have worked not to compile. ("This is a breaking change and forbids some safe code which is legal today.").
We can go around this if we lower the restriction only to the trait members function that actually need it, e.g. this compiles:
trait NodeLike {
fn method_foo(&self) -> Self
where
Self: Sized;
}
fn main() {
let s: Box<NodeLike> = panic!();
// Compiles!
}
However, we cannot call those Self: Sized
methods via a trait object, and this is a limitation that is explained elsewhere. Here, calling s.method_foo();
will break compilation.
Note that the Self: Sized
constraint limits compilation even if the method does not make use of Self
at all and could have been a callable trait object method otherwise.