Dangling reference, checked by miri
⚓ Rust 📅 2025-07-29 👤 surdeus 👁️ 10Are 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
🏷️ Rust_feed