Issue implementing trait methods within trait

I wish to implement method within a trait, but it gives an error: "the size for values of type Self cannot be known at compilation time
the trait std::marker::Sized is not implemented for Self. all local variables must have a statically known size"

trait MyTrait{
    fn foo(&self) -> Self; 

    fn problematic_function(&self) -> Self{
        let c = self.foo();  // this gives an error. 
    }
}

This error occurs because MyTrait might be implemented for a type whose values do not have a fixed size that's known at compile time, like [u8] or the trait object dyn MyTrait. In that situation you can't bind the value returned by MyTrait::foo to a local variable, because values of dynamically-sized type can't (currently) be kept on the stack.

The simplest fix is to add a where Self: Sized bound to MyTrait::problematic_function:

trait MyTrait {
    fn foo(&self) -> Self; 

    fn problematic_function(&self) -> Self
    where
        Self: Sized,
    {
        let c = self.foo();
        ... 
    }
}

This tells the compiler not to allow calling that method on values of dynamically-sized type.

You can also declare trait MyTrait: Sized if all your methods need to deal with Self values.

1 Like

This is great! QQ: then how do I make sure that my custom struct satisfy this "Sized" constraint?

The only situation where a type you define yourself wouldn't be Sized is when it has a !Sized (not Sized) field, e.g.

struct Blah([u8]);

If you do want to keep some !Sized type in a struct, you can use Box.