Soundness of reinterpreting immutable references to transmute compatible types

⚓ Rust    📅 2026-01-05    👤 surdeus    👁️ 4      

surdeus

Is it sound to transmute &B to &A when A and B have the same known layout, alignment valid bit patterns?

I found validity.reference-box but it's phrased:

  • A reference or Box<T> must be aligned and non-null, it cannot be dangling, and it must point to a valid value (in case of dynamically sized types, using the actual dynamic type of the pointee as determined by the metadata). Note that the last point (about pointing to a valid value) remains a subject of some debate.

Where do I find the definition of a "valid value"? Since A and B satisfy the rules for transmutation (both ways), does that mean that "valid values" of one are valid values of another with this definition of valid value?

use std::ptr::NonNull;

#[derive(Debug)]
#[repr(transparent)]
struct A(*mut u8);

#[derive(Debug)]
#[repr(transparent)]
struct B(Option<NonNull<u8>>);

impl From<A> for B {
    fn from(value: A) -> Self {
        Self(NonNull::new(value.0))
    }
}

impl std::ops::Deref for B {
    type Target = A;
    
    fn deref(&self) -> &Self::Target {
        // SAFETY: no idea
        // https://doc.rust-lang.org/reference/behavior-considered-undefined.html#r-undefined.validity.reference-box
        // is 
        unsafe { &*std::ptr::from_ref(self).cast() }
    }
}

fn main() {
    let a = A(std::ptr::dangling_mut());
    
    let b = B::from(a);
    
    // Conveniently auto-derefs.
    let r: &A = &b;
    
    dbg!(r);
}

Rust Playground

This must have been asked already but I struggled to find this particular immutable reference casting of transmute compatible types.

1 post - 1 participant

Read full topic

🏷️ Rust_feed