Newtype wrappers and `impl Deref`

Say I've got the following code

  • From a library
struct OtherParent(..);
struct OtherChild(..);

impl Deref for OtherParent {
    type Target = OtherChild;

    // ...
}
  • and then in my own code
#[repr(transparent)]
struct Parent(OtherParent);

#[repr(transparent)]
struct Child(OtherChild);

impl Deref for Parent {
    type Target = Child;

    fn deref(&self) -> &Self::Target {
        unsafe { mem::transmute::<&OtherChild, &Child>(&*self.0) }
    }
}

So I'm derefing to OtherChild and then just reinterpreting that as Child since their representation is the same? Is this correct? Is there a better way of achieving what I'm trying to achieve (shadowing the Deref with my newtypes)?

transmute is often a footgun, and pointers can be cast using the as operator.

Other than that it seems fine.

1 Like

I put the types I'm expecting into the transmute, to make sure it's doing exactly what I'm expecting.

How would this look using as?

fn deref(&self) -> &Self::Target {
   unsafe { &*(&*self.0 as *const OtherChild as *const _) }
}

What’s the reason for wanting to do Deref “shadowing”? Are you trying to hide the lib types from your users? Why use Deref on your end rather than normal methods that return Child that internally borrows OtherChild?

For now, I'm just mirroring the structure of the library, while hiding the inner types.