Well, I got a variation of this also working for you—AsObj
is not generic on Trait
here—but you could probably do that. The tricks are to
- implement
AsObj
for references to your traits/structs so that yourSelf
isSized
, and - implement
AsObj
for&Trait
instead of requiringtrait Trait: AsObj<Trait>
which doesn't seem to be strictly necessary (conceptually,&Trait
should always be coercible to&Trait
without explicitly extendingAsObj
).
Playground
Edit 3: Playground Version with Obj<Trait>
as well.
However, I haven't quite wrapped my mind around why the original error regarding Sized
even happens. It's probably due to the same thing, but I oughta just go to bed now.
Edit: Aaaaah, I can't sleep because of this! I simplified the playground example above to really understand the Sized
constraint, and it feels like a bug or shortcoming in the compiler. Here's the issue that lays out the bare minimum, but the devs may provide some insights as to the genericity of unsized types.
Edit 2: Failing to sleep even more, I recalled this thread where I learned about the as-yet unstable Unsize marker trait which serves the same purpose as your AsObj
trait, allowing you to support both Sized
types implementing &Trait
and trait objects. Et voilà: playground.
Edit 3: Of course, in the morning, it aaaaaall makes sense now. Someone else pointed the same thing out on the issue as well. Trait objects consist of a pair of thin pointers—one to the vtable and one thin pointer to the object itself. Unfortunately, DSTs are fat pointers, so that when trying to convert, e.g., [Type]
(fat pointer) to &Trait
, you need the trait object to be a superfat pointer (at least 3-pointer-sized), which rust doesn't currently support. A special case is &Trait
→ &Trait
which doesn't need any conversion to a trait object as it's already one. Unsize<Trait>
handles both the convertible cases (Type: Trait + Sized
and &Trait
).