Why is Sized required in trait?


The following code

trait Foo {
    fn call_mut(&mut self);

    fn call_once(mut self) {

produces the following error:

test37.rs:4:18: 4:26 error: the trait bound `Self: std::marker::Sized` is not satisfied [E0277]
test37.rs:4     fn call_once(mut self) {
test37.rs:4:18: 4:26 help: run `rustc --explain E0277` to see a detailed explanation
test37.rs:4:18: 4:26 help: consider adding a `where Self: std::marker::Sized` bound
test37.rs:4:18: 4:26 note: all local variables must have a statically known size
error: aborting due to previous error

Why? As I understand it, Rust monomorphizes trait except when using trait objects, so for each concrete T, it provides a separate “fn call_once(mut self: T)” implementation, where it must know the size of T.



Not all concrete types have sizes. There are unsized types like str and [u8] whose sizes are not known by the compiler, and therefore cannot be used without a &-reference in front. The compiler checks traits for every conceivable implementation, including impl Foo for str for which the method would be invalid. If you don’t plan to use your trait for such unsized types, you can explicitly tell the compiler this by trait Foo: Sized.