Dangling reference, checked by miri

⚓ Rust    📅 2025-07-29    👤 surdeus    👁️ 10      

surdeus

Warning

This post was published 127 days ago. The information described in this article may have changed.

Are there further news about the requirements for references to be valid?
According to The Reference undefined.validity.reference-box, a reference "cannot be dangling" and "must point to a valid value" if it're to be valid. Then one would infer that for a type containing references, a reference to said type would require its pointee references to all be non-dangling to be a valid value. But in the following code:

use std::mem::transmute;

struct A<'b>(&'b mut usize, usize);
impl<'any> A<'any>
{
    fn get(&self) -> usize { self.1 }
    fn borrow<'a, 'b: 'a>(&'b mut self) -> &'a mut usize
    {
        self.0
    }
    fn set(&mut self, u: usize)
    {
        self.1 = u;
    }
}

fn main()
{
    let mut buf = Box::new(0);
    let mut a = unsafe
    {
        let mut a = transmute::<_, A<'static>>(A(&mut *buf, 42));
        *a.borrow() = 43;
        a
    };
    println!("{}", *buf);
    // post drop, `a.0` should be a dangling (but offline) reference.
    drop(buf);
    // as miri doesn't report ub, both `&mut a` and `&a` are valid values.
    a.set(42);
    println!("{}", a.get());
    /* uncommenting this, miri reports:
     *
     * error: Undefined Behavior: constructing invalid value: encountered
     * a dangling reference (use-after-free)
     */
    // a.borrow();
    /* uncommenting this, miri reports:
     *
     * error: Undefined Behavior: constructing invalid value at .0:
     * encountered a dangling reference (use-after-free)
     */
    // let b = a;
}

In the above code, a.set(42) creates a &'_ mut A<'static> during call, the pointee of which seems to be an invalid value (miri calls that out when moving a to b).
miri didn't call that reference out, is it a bug or is the &'static mut usize field (originally a no-longer-live &'_ mut usize) valid until being coerced into the borrow fn return type?
In the case that it is a bug, my cargo miri --version --verbose output is miri 0.1.0 (2a023bf80a 2025-07-10).

2 posts - 2 participants

Read full topic

🏷️ Rust_feed