Storing the size in the box?

It appears I may have backed myself into a corner, actually:

#![feature(ptr_metadata)]

use {
    erasable::Erasable,
    std::{marker::PhantomData, ptr},
};

#[repr(C)]
pub struct Indyn<Dyn: ?Sized, T: ?Sized = Dyn> {
    phantom: PhantomData<Dyn>,
    metadata: <Dyn as ptr::Pointee>::Metadata,
    inner: T,
}

unsafe impl<Dyn: ?Sized> Erasable for Indyn<Dyn> {
    unsafe fn unerase(this: erasable::ErasedPtr) -> ptr::NonNull<Self> {
        let metadata = ptr::read::<<Dyn as ptr::Pointee>::Metadata>(this.as_ptr() as *mut _);
        let this: *mut Dyn = ptr::from_raw_parts_mut(this.as_ptr() as *mut _, metadata);
        ptr::NonNull::new_unchecked(this as *mut Indyn<Dyn>)
    }

    const ACK_1_1_0: bool = true;
}

This works, and miri is happy to accept it.

Example
macro_rules! indyn {
    ($t:expr; as $d:ty) => {{
        let t = $t;
        let p: &$d = &t;
        Indyn {
            phantom: PhantomData,
            metadata: ptr::metadata(p),
            inner: t,
        }
    }};
}

fn main() {
    let b: Box<Indyn<dyn Any>> = Box::new(indyn!(0usize; as dyn Any));
    println!("type_name: {}", std::any::type_name_of_val(&b));
    println!("size_of  : {}", std::mem::size_of_val(&b));

    let thin = erasable::erase(ptr::NonNull::new(Box::into_raw(b)).unwrap());
    println!("type_name: {}", std::any::type_name_of_val(&thin));
    println!("size_of  : {}", std::mem::size_of_val(&thin));

    let b: Box<Indyn<dyn Any>> = unsafe { Box::from_raw(Indyn::unerase(thin).as_ptr()) };
    println!("type_name: {}", std::any::type_name_of_val(&b));
    println!("size_of  : {}", std::mem::size_of_val(&b));

    dbg!(b.downcast_ref::<usize>());
}
type_name: alloc::boxed::Box<indyn::Indyn<dyn core::any::Any>>
size_of  : 16
type_name: core::ptr::non_null::NonNull<erasable::priv_in_pub::Erased>
size_of  : 8
type_name: alloc::boxed::Box<indyn::Indyn<dyn core::any::Any>>
size_of  : 16
[src\main.rs:63] b.downcast_ref::<usize>() = Some(
    0,
)

Unfortunately...

error[E0119]: conflicting implementations of trait `erasable::Erasable` for type `Indyn<_>`
  --> src\main.rs:17:1
   |
17 | unsafe impl<Dyn: ?Sized> Erasable for Indyn<Dyn> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: conflicting implementation in crate `erasable`:
           - impl<T> Erasable for T;

the blanket impl of Erasable for any sized T conflicts with the specific impl for Indyn. I still stand by the blanket impl, so I guess arbitrary DST metadata support for erasable::Thin will need to wait for both ptr_metadata and min_specialization :cry:


(I'm sorry-not-sorry; Indyn is a pun on "linline")