MIRI error, But I have removed mutable reference to avoid UB

⚓ Rust    📅 2025-10-31    👤 surdeus    👁️ 7      

surdeus

Warning

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

I am not good at English. Sorry if there are any funny expressions.


I know that multiple mutable references to the same value result in UB (undefined behavior).

So I tried keeping one as a mutable reference and one as a pointer (In the actual code, one is a part of the other, but I'm simplifying here). Then, I thought that when converting back from the pointer to the mutable reference, I just drop the first mutable reference.

The code ran as expected. However, verification on MIRI resulted in error (There was a link about error detail, but I couldn't understand it even after reading it).

Please help me.

#![allow(dead_code)]

#[test]
fn test() {
    let mut var = ValHolder { val: MyVal(1) };
    TwoWayMutRef::new(&mut var).method();
}

pub struct ValHolder {
    val: MyVal,
}

pub struct TwoWayMutRef<'a> {
    mut_ptr: *mut MyVal,
    mut_ref: Option<&'a mut MyVal>,
}

impl<'a> TwoWayMutRef<'a> {
    pub fn new(vh: &'a mut ValHolder) -> Self {
        Self {
            mut_ptr: (&mut vh.val) as *mut _,
            mut_ref: Some(&mut vh.val), // 👈 If `None`, everything is OK.
        }
    }

    pub fn method(&mut self) {
        // 🗑️ Remove mutable reference (to avoid mutable reference alias UB).
        Option::take(&mut self.mut_ref);

        // ❌ Restore mutable reference from pointer (MIRI reports UB. why?).
        let val = unsafe { &mut *self.mut_ptr };
        val.do_something();
    }
}

struct MyVal(i32);
impl MyVal {
    fn do_something(&mut self) {}
}

MIRI Error excerpt

test test ... error: Undefined Behavior: trying to retag from <145113> for Unique permission at alloc45233[0x0], but that tag does not exist in the borrow stack for this location
  --> src\lib.rs:31:28
   |
31 |         let val = unsafe { &mut *self.mut_ptr };
   |                            ^^^^^^^^^^^^^^^^^^ this error occurs as part of retag at alloc45233[0x0..0x4]
   |
   = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
   = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: <145113> was created by a SharedReadWrite retag at offsets [0x0..0x4]
  --> src\lib.rs:21:22

4 posts - 2 participants

Read full topic

🏷️ Rust_feed