1 #![feature(maybe_uninit_extra)]
2 use std::mem::MaybeUninit;
3 use std::cell::{Cell, RefCell, UnsafeCell};
4
main()5 fn main() {
6 aliasing_mut_and_shr();
7 aliasing_frz_and_shr();
8 into_interior_mutability();
9 unsafe_cell_2phase();
10 }
11
aliasing_mut_and_shr()12 fn aliasing_mut_and_shr() {
13 fn inner(rc: &RefCell<i32>, aliasing: &mut i32) {
14 *aliasing += 4;
15 let _escape_to_raw = rc as *const _;
16 *aliasing += 4;
17 let _shr = &*rc;
18 *aliasing += 4;
19 // also turning this into a frozen ref now must work
20 let aliasing = &*aliasing;
21 let _val = *aliasing;
22 let _escape_to_raw = rc as *const _; // this must NOT unfreeze
23 let _val = *aliasing;
24 let _shr = &*rc; // this must NOT unfreeze
25 let _val = *aliasing;
26 }
27
28 let rc = RefCell::new(23);
29 let mut bmut = rc.borrow_mut();
30 inner(&rc, &mut *bmut);
31 drop(bmut);
32 assert_eq!(*rc.borrow(), 23+12);
33 }
34
aliasing_frz_and_shr()35 fn aliasing_frz_and_shr() {
36 fn inner(rc: &RefCell<i32>, aliasing: &i32) {
37 let _val = *aliasing;
38 let _escape_to_raw = rc as *const _; // this must NOT unfreeze
39 let _val = *aliasing;
40 let _shr = &*rc; // this must NOT unfreeze
41 let _val = *aliasing;
42 }
43
44 let rc = RefCell::new(23);
45 let bshr = rc.borrow();
46 inner(&rc, &*bshr);
47 assert_eq!(*rc.borrow(), 23);
48 }
49
50 // Getting a pointer into a union with interior mutability used to be tricky
51 // business (https://github.com/rust-lang/miri/issues/615), but it should work
52 // now.
into_interior_mutability()53 fn into_interior_mutability() {
54 let mut x: MaybeUninit<(Cell<u32>, u32)> = MaybeUninit::uninit();
55 x.as_ptr();
56 x.write((Cell::new(0), 1));
57 let ptr = unsafe { x.assume_init_ref() };
58 assert_eq!(ptr.1, 1);
59 }
60
61 // Two-phase borrows of the pointer returned by UnsafeCell::get() should not
62 // invalidate aliases.
unsafe_cell_2phase()63 fn unsafe_cell_2phase() { unsafe {
64 let x = &UnsafeCell::new(vec![]);
65 let x2 = &*x;
66 (*x.get()).push(0);
67 let _val = (*x2.get()).get(0);
68 } }
69