We should imho leave dyn Trait
unsized but instead use small box optimizations, although our current smallbox
crate wastes one usize
unnecessarily.
You instead want a SmallBox<T,Size>
type that determines whether its internal Size
holds T
, or whether the first usize
contains a Box
, by invoking mem::size_of_val
with the vtable provided by dyn Trait
and ptr::null
, ala https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=9f175095c2f072317c31d3e5c68e291b
It works because mem::size_of_val
never dereferences its data pointer. All dyn Trait
record their size n their vtable. We cannot create dyn Trait
s from unsized types, but even those keep their size in the fat pointer.
We'd make alloc
an optional crate feature, so this SmallBox
crate still works without std or even alloc. At this point, you define an error type SmallBox<dyn Error,usize>
that exists without without std or alloc, provided your Error
trait avoids std too.