Vec::push invalidates interior references even when it does not reallocate (original) (raw)
To my knowledge, the following code is intended to be legal:
fn main() {
let mut v = Vec::with_capacity(10);
v.push(0);
let v0 = unsafe { &*(&v[0] as *const _) }; // laundering the lifetime -- we take care that v does not reallocate, so that's okay.
v.push(1);
let _val = *v0;
}
However, Miri currently flags this as UB. The reason is that Vec::push implicitly (through auto-deref) calls deref_mut to create a &mut [T] covering all elements in the vector, which overlaps with our reference v0 in the example code above. Overlapping shared and mutable references are prohibited by Stacked Borrows.