| //@compile-flags: -Zmiri-tree-borrows |
| #![feature(box_as_ptr)] |
| #[path = "../../utils/mod.rs"] |
| #[macro_use] |
| mod utils; |
| |
| use std::cell::UnsafeCell; |
| |
| fn main() { |
| let cell = UnsafeCell::new(42); |
| let box1 = Box::new(cell); |
| |
| unsafe { |
| let ptr1: *mut UnsafeCell<i32> = Box::into_raw(box1); |
| name!(ptr1); |
| |
| let mut box2 = Box::from_raw(ptr1); |
| // `ptr2` will be a descendant of `ptr1`. |
| let ptr2: *mut UnsafeCell<i32> = Box::as_mut_ptr(&mut box2); |
| name!(ptr2); |
| |
| // We perform a write through `x`. |
| // Because `ptr1` is ReservedIM, a child write will make it transition to Unique. |
| // Because `ptr2` is ReservedIM, a foreign write doesn't have any effect on it. |
| let x = (*ptr1).get(); |
| *x = 1; |
| |
| // We can still read from `ptr2`. |
| let val = *(*ptr2).get(); |
| assert_eq!(val, 1); |
| |
| let alloc_id = alloc_id!(ptr1); |
| print_state!(alloc_id); |
| } |
| } |