Search code examples
rustunsafe

Can you cast a memory address as a usize into a reference with a lifetime?


I know we can cast from reference -> raw pointer -> address (usize), but can we do it backwards especially with lifetime annotations? For example, I have following code:

struct Name<'a> {
    name: &'a str,
}

impl<'a> Name<'a> {
    fn to_addr<'b>(&'b self) -> usize { /* ... */ }
    fn from_addr<'b>(address: usize) -> &'b Name<'a> {
        // assuming the address is valid,
        // is this even possible to return an reference with both lifetimes?
    }
}

Solution

  • It's unsafe, but yes:

    fn from_addr<'b>(address: usize) -> &'b Name<'a> {
        unsafe { &*(address as *const Self) }
    }
    

    You have to ensure Rust's memory safety requirements yourself: the pointer must be non-null, non-dangling, aligned, not mutably aliased, etc. on top of ensuring the lifetimes are correct.

    I'd actually mark this whole function as unsafe since the lifetime 'b (and depending on usage 'a) is determined at the call-site. The caller should know that there are guarantees it needs to ensure in order to use it safely.

    unsafe fn from_addr<'b>(address: usize) -> &'b Name<'a> {
        &*(address as *const Self)
    }