//@ known-bug: #114484
use std::marker::PhantomData;

trait MyTrait {
    fn virtualize(&self) -> &dyn MyTrait;
}

struct VirtualWrapper<T, const L: u8>(T);

impl<T, const L: u8> VirtualWrapper<T, L> {
    pub fn wrap(value: &T) -> &Self {
        unsafe { &*(value as *const T as *const Self) }
    }
}

impl<T: MyTrait + 'static, const L: u8> MyTrait for VirtualWrapper<T, L> {
    fn virtualize(&self) -> &dyn MyTrait {
        unsafe { virtualize_my_trait(L, self) }
        // unsafe { virtualize_my_trait(L, &self.0) }    // <-- this code fixes the problem
    }
}

const unsafe fn virtualize_my_trait<T>(level: u8, obj: &T) -> &dyn MyTrait
where
    T: MyTrait + 'static,
{
    const fn gen_vtable_ptr<T, const L: u8>() -> *const ()
    where
        T: MyTrait + 'static,
    {
        let [_, vtable] = unsafe {
            std::mem::transmute::<*const dyn MyTrait, [*const (); 2]>(std::ptr::null::<
                VirtualWrapper<T, L>,
            >())
        };
        vtable
    }

    struct Vtable<T>(PhantomData<T>);

    impl<T> Vtable<T>
    where
        T: MyTrait + 'static,
    {
        const LEVELS: [*const (); 2] = [gen_vtable_ptr::<T, 1>(), gen_vtable_ptr::<T, 2>()];
    }

    let vtable = Vtable::<T>::LEVELS[(level != 0) as usize];

    let data = obj as *const T as *const ();
    let ptr: *const dyn MyTrait = std::mem::transmute([data, vtable]);

    &*ptr
}

struct SomeData<const N: usize>([u8; N]);

impl<const N: usize> MyTrait for SomeData<N> {
    fn virtualize(&self) -> &dyn MyTrait {
        VirtualWrapper::<Self, 0>::wrap(self)
    }
}

fn main() {
    let test = SomeData([0; 256]);
    test.virtualize();
}
