This rewrites the GcBox internals to use a manually-implemented vtable instead of relying on dyn Collect, enabling two improvements:
with GcBox now self-contained, the unsizing coercion in CollectionContext::trace/write_barrier is no longer necessary, which means that Gc pointers can support unsized types;
similarly, the only place where a T: Collect bound is now required is during allocation, this makes removing the bound on Gc (like in #22) viable.
This could also allow removing the Self: Sized bound on Collect::needs_trace(), but this is technically a breaking change (making the trait non-object-safe) so idk if it should be done?
A small wrinkle though: unsized coercions for custom smart pointers aren't possible in stable Rust, so I've added an unsize!(gc => SomeUnsizedType) macro instead; feel free to bikeshed the syntax if you don't agree with my choice.
This rewrites the
GcBox
internals to use a manually-implemented vtable instead of relying ondyn Collect
, enabling two improvements:GcBox
now self-contained, the unsizing coercion inCollectionContext::trace/write_barrier
is no longer necessary, which means thatGc
pointers can support unsized types;T: Collect
bound is now required is during allocation, this makes removing the bound onGc
(like in #22) viable.This could also allow removing the
Self: Sized
bound onCollect::needs_trace()
, but this is technically a breaking change (making the trait non-object-safe) so idk if it should be done?A small wrinkle though: unsized coercions for custom smart pointers aren't possible in stable Rust, so I've added an
unsize!(gc => SomeUnsizedType)
macro instead; feel free to bikeshed the syntax if you don't agree with my choice.