I would like to implement a FixedSizeBox which behaves like the Box but owns the memory in which the object is stored. I introduced an additional parameter CAPACITY which defines the size of the memory which the FixedSizeBox will own.
The problem I encounter is that I am unable to use dyn SomeTrait as FixedSizeBox type and call new with a specific type.
Let's assume I have a trait SomeTrait and a struct A which implements that trait.
trait SomeTrait {}
struct A(u8);
impl SomeTrait for A {}
When I would like to store any object which implements SomeTrait in a Box I can write
let mut a: Box<dyn SomeTrait>;
a = Box::new(A { 0: 0 });
For the FixedSizeBox I would like to have the same functionality and implemented it like:
pub struct FixedSizeBox<const CAPACITY: usize, T: ?Sized> {
_marker: PhantomData<T>,
}
impl<const CAPACITY: usize, T> FixedSizeBox<CAPACITY, T> {
pub fn new(_: T) -> FixedSizeBox<CAPACITY, T> {
FixedSizeBox::<CAPACITY, T> {
_marker: PhantomData,
}
}
}
When I use it in the same fashion as the Box the compiler fails:
let mut b: StackBox<128, dyn SomeTrait>;
// assigning a specific type leads to
// mismatched types
// expected struct `StackBox<dyn SomeTrait, 128_usize>`
// found struct `StackBox<A, {_: usize}>` (rustc E0308)
b = StackBox::new(A { 0: 0 });
I looked into the Box and Rc implementations but was unable to figure out how rust actually realized this. Is there some trait missing?
As a side constraint, I would like to use stable rust. I could figure out that the nightly feature CoerceUnsized
impl<T, U> std::ops::CoerceUnsized<StackBox<U>> for FixedSizeBox<T>
where
T: std::marker::Unsize<U> + ?Sized,
U: ?Sized,
{
}
solves the issue but I would like to understand how this is realized in stable rust for Box so that I can apply it to the FixedSizeBox.