Skip to content

Removing an identity pointer cast can cause vtable kind unification for projected types to fail #103384

Closed
@CAD97

Description

@CAD97

[playground]

use core::marker::PhantomData;

pub trait TypeTag<'a>: 'static {
    type Type: ?Sized;
}

pub unsafe trait PointerTag<'a>: TypeTag<'a>
where
    Self::Type: Sized,
{
    type Pointee: TypeTag<'a>;

    fn into_raw(this: Self::Type) -> *mut <Self::Pointee as TypeTag<'a>>::Type;
}

pub struct Rc<I>(PhantomData<I>);

impl<'a, I: TypeTag<'a>> TypeTag<'a> for Rc<I> {
    type Type = std::rc::Rc<I::Type>;
}

unsafe impl<'a, I: TypeTag<'a>> PointerTag<'a> for Rc<I> {
    type Pointee = I;

    fn into_raw(this: Self::Type) -> *mut I::Type {
        std::rc::Rc::into_raw(this) /* as *const I::Type */ as *mut I::Type
    }
}

results in the error

error[[E0606]](https://doc.rust-lang.org/nightly/error-index.html#E0606): casting `*const <I as TypeTag<'_>>::Type` as `*mut <I as TypeTag<'a>>::Type` is invalid
  --> src/lib.rs:26:9
   |
26 |         std::rc::Rc::into_raw(this) /* as *const I::Type */ as *mut I::Type
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: vtable kinds may not match

For more information about this error, try `rustc --explain E0606`.

Uncommenting the as *const I::Type lets this compile without error.

Meta

playground 1.66.0-nightly (2022-10-20 dcb3761)

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions