File tree Expand file tree Collapse file tree 2 files changed +36
-3
lines changed
tests/compile-fail/stacked_borrows Expand file tree Collapse file tree 2 files changed +36
-3
lines changed Original file line number Diff line number Diff line change @@ -3,8 +3,13 @@ use std::cell::UnsafeCell;
3
3
fn main ( ) { unsafe {
4
4
let c = & UnsafeCell :: new ( UnsafeCell :: new ( 0 ) ) ;
5
5
let inner_uniq = & mut * c. get ( ) ;
6
- let inner_shr = & * inner_uniq; // a SharedRW with a tag
7
- * c. get ( ) = UnsafeCell :: new ( 1 ) ; // invalidates the SharedRW
6
+ // stack: [c: SharedReadWrite, inner_uniq: Unique]
7
+
8
+ let inner_shr = & * inner_uniq; // adds a SharedReadWrite
9
+ // stack: [c: SharedReadWrite, inner_uniq: Unique, inner_shr: SharedReadWrite]
10
+
11
+ * c. get ( ) = UnsafeCell :: new ( 1 ) ; // invalidates inner_shr
12
+ // stack: [c: SharedReadWrite]
13
+
8
14
let _val = * inner_shr. get ( ) ; //~ ERROR borrow stack
9
- let _val = * inner_uniq. get ( ) ;
10
15
} }
Original file line number Diff line number Diff line change
1
+ use std:: cell:: UnsafeCell ;
2
+ use std:: mem;
3
+
4
+ // Like `&mut *x.get()`, but without intermediate raw pointers.
5
+ #[ allow( mutable_transmutes) ]
6
+ unsafe fn unsafe_cell_get < T > ( x : & UnsafeCell < T > ) -> & ' static mut T {
7
+ mem:: transmute ( x)
8
+ }
9
+
10
+ fn main ( ) { unsafe {
11
+ let c = & UnsafeCell :: new ( UnsafeCell :: new ( 0 ) ) ;
12
+ let inner_uniq = & mut * c. get ( ) ;
13
+ let inner_shr = & * inner_uniq;
14
+ // stack: [c: SharedReadWrite, inner_uniq: Unique, inner_shr: SharedReadWrite]
15
+
16
+ let _val = c. get ( ) . read ( ) ; // invalidates inner_uniq
17
+ // stack: [c: SharedReadWrite, inner_uniq: Disabled, inner_shr: SharedReadWrite]
18
+
19
+ // We have to be careful not to add any raw pointers above inner_uniq in
20
+ // the stack, hence the use of unsafe_cell_get.
21
+ let _val = * unsafe_cell_get ( inner_shr) ; // this still works
22
+
23
+ * c. get ( ) = UnsafeCell :: new ( 0 ) ; // now inner_shr gets invalidated
24
+ // stack: [c: SharedReadWrite]
25
+
26
+ // now this does not work any more
27
+ let _val = * inner_shr. get ( ) ; //~ ERROR borrow stack
28
+ } }
You can’t perform that action at this time.
0 commit comments