//@revisions: stack tree //@[tree]compile-flags: -Zmiri-tree-borrows trait S: Sized { fn tpb(&mut self, _s: Self) {} } impl S for i32 {} fn two_phase1() { let mut x = 3; x.tpb(x); } fn two_phase2() { let mut v = vec![]; v.push(v.len()); } fn two_phase3(b: bool) { let mut x = &mut vec![]; let mut y = vec![]; x.push(( { if b { x = &mut y; } 22 }, x.len(), )); } fn two_phase_raw() { let x: &mut Vec = &mut vec![]; #[allow(unreachable_code)] // The `push` itself never gets reached. x.push({ // Unfortunately this does not trigger the problem of creating a // raw ponter from a pointer that had a two-phase borrow derived from // it because of the implicit &mut reborrow. let raw = x as *mut _; unsafe { *raw = vec![1]; } return; }); } fn two_phase_overlapping1() { let mut x = vec![]; let p = &x; x.push(p.len()); } fn two_phase_overlapping2() { use std::ops::AddAssign; let mut x = 1; let l = &x; x.add_assign(x + *l); } fn main() { two_phase1(); two_phase2(); two_phase3(false); two_phase3(true); two_phase_raw(); two_phase_overlapping1(); two_phase_overlapping2(); }