3

Consider the following code:

unsafe {
    let mut s = "".to_string();
    let r = &mut s;
    let ptr = r as *mut String;
        
    r.push('a');
    (*ptr).push('b');
    r.push('c');
    (*ptr).push('d');
        
    println!("{}", r);
}

Playground.

I would think that this is a clear violation of Rust aliasing rules: I have a mutable reference and a mutable pointer, and there are interleaving writes using both of them. However, MIRI lets it pass. What am I missing?

rubo
  • 377
  • 1
  • 8
  • 1
    Hmm... I don't have time to re-read Stacked Borrows now and I don't remember the full details, but pointers put a SharedReadWrite on the borrow stack and maybe it does not invalidate the Unique of the reference or they're switching? – Chayim Friedman Dec 05 '22 at 11:41
  • Thanks for the hint, I will probably have to get acquainted with Stacked Borrows after all to fully understand aliasing. – rubo Dec 05 '22 at 11:43
  • 1
    Ah, I think I got it: Each time you dereference the pointer it puts a SharedReadWrite on the stack, but the Unique of the reference is still behind. Dereferencing the reference pops the SharedReadWrite and reaches the Unique so success, and derefing the pointer just reintroduces the SharedReadWrite. But take this with a grain of salt; I'm still not sure. – Chayim Friedman Dec 05 '22 at 11:47
  • Observation: changing it to `let ptr = (&mut s) as *mut String;` and moving it above `let r = &mut s;` does result in a Miri error. – PitaJ Dec 05 '22 at 17:21

0 Answers0