Open
Description
The following traits are accepted, but not object safe:
pub trait MyTrait {
fn deserialize(input: u32) -> Self;
}
pub trait YourTrait {
type Output: ?Sized;
fn deserialize(&self, input: u32) -> Self::Output;
}
On the other hand, the following traits are rejected saying the trait bound Self: std::marker::Sized is not satisfied
:
pub trait MyTrait {
fn deserialize(input: u32) -> Option<Self>;
}
pub trait YourTrait {
type Output: ?Sized;
fn deserialize(&self, input: u32) -> Option<Self::Output>;
}
The error makes sense in principle, but
- (a) it is really confusing that it is okay to have unsized return types (where usually the same check would apply!), but not return enums with unsized types inside them. What seems to happen here is that there is a special rule if the return type is unsized to drop object safety (if the type is
Self
) or do nothing (otherwise) instead of complaining. - (b) The fix is far from obvious: One has to add
Sized
as a supertrait toMyTrait
. Given thatSized
is usually added implicitly, people will run into this without ever having dealt withSized
before (and in fact, that's what just happened when a friend asked me about this). The error will certainly not help with finding this.
Both of these points would be fixed if that exception for unsized argument/return types would be extended to also cover the above cases.