]> git.lizzy.rs Git - rust.git/blob - tests/run-pass/stacked-borrows/interior_mutability.rs
33f44d0093ed4d4886961dab416ef15d796d25a4
[rust.git] / tests / run-pass / stacked-borrows / interior_mutability.rs
1 #![feature(maybe_uninit, maybe_uninit_ref)]
2 use std::mem::MaybeUninit;
3 use std::cell::Cell;
4 use std::cell::RefCell;
5
6 fn main() {
7     aliasing_mut_and_shr();
8     aliasing_frz_and_shr();
9     into_interior_mutability();
10 }
11
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
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.
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.get_ref() };
58     assert_eq!(ptr.1, 1);
59 }