1
1
// compile-flags: -Zmiri-retag-fields
2
- use std:: cell:: { Cell , RefCell , UnsafeCell } ;
2
+ use std:: cell:: { Cell , Ref , RefCell , RefMut , UnsafeCell } ;
3
3
use std:: mem:: { self , MaybeUninit } ;
4
4
5
5
fn main ( ) {
@@ -9,6 +9,10 @@ fn main() {
9
9
unsafe_cell_2phase ( ) ;
10
10
unsafe_cell_deallocate ( ) ;
11
11
unsafe_cell_invalidate ( ) ;
12
+ refcell_basic ( ) ;
13
+ ref_protector ( ) ;
14
+ ref_mut_protector ( ) ;
15
+ rust_issue_68303 ( ) ;
12
16
}
13
17
14
18
fn aliasing_mut_and_shr ( ) {
@@ -100,3 +104,72 @@ fn unsafe_cell_invalidate() {
100
104
// So using raw1 invalidates raw2.
101
105
f ( unsafe { mem:: transmute ( raw2) } , raw1) ;
102
106
}
107
+
108
+ fn refcell_basic ( ) {
109
+ let c = RefCell :: new ( 42 ) ;
110
+ {
111
+ let s1 = c. borrow ( ) ;
112
+ let _x: i32 = * s1;
113
+ let s2 = c. borrow ( ) ;
114
+ let _x: i32 = * s1;
115
+ let _y: i32 = * s2;
116
+ let _x: i32 = * s1;
117
+ let _y: i32 = * s2;
118
+ }
119
+ {
120
+ let mut m = c. borrow_mut ( ) ;
121
+ let _z: i32 = * m;
122
+ {
123
+ let s: & i32 = & * m;
124
+ let _x = * s;
125
+ }
126
+ * m = 23 ;
127
+ let _z: i32 = * m;
128
+ }
129
+ {
130
+ let s1 = c. borrow ( ) ;
131
+ let _x: i32 = * s1;
132
+ let s2 = c. borrow ( ) ;
133
+ let _x: i32 = * s1;
134
+ let _y: i32 = * s2;
135
+ let _x: i32 = * s1;
136
+ let _y: i32 = * s2;
137
+ }
138
+ }
139
+
140
+ // Adding a Stacked Borrows protector for `Ref` would break this
141
+ fn ref_protector ( ) {
142
+ fn break_it ( rc : & RefCell < i32 > , r : Ref < ' _ , i32 > ) {
143
+ // `r` has a shared reference, it is passed in as argument and hence
144
+ // a protector is added that marks this memory as read-only for the entire
145
+ // duration of this function.
146
+ drop ( r) ;
147
+ // *oops* here we can mutate that memory.
148
+ * rc. borrow_mut ( ) = 2 ;
149
+ }
150
+
151
+ let rc = RefCell :: new ( 0 ) ;
152
+ break_it ( & rc, rc. borrow ( ) )
153
+ }
154
+
155
+ fn ref_mut_protector ( ) {
156
+ fn break_it ( rc : & RefCell < i32 > , r : RefMut < ' _ , i32 > ) {
157
+ // `r` has a shared reference, it is passed in as argument and hence
158
+ // a protector is added that marks this memory as inaccessible for the entire
159
+ // duration of this function
160
+ drop ( r) ;
161
+ // *oops* here we can mutate that memory.
162
+ * rc. borrow_mut ( ) = 2 ;
163
+ }
164
+
165
+ let rc = RefCell :: new ( 0 ) ;
166
+ break_it ( & rc, rc. borrow_mut ( ) )
167
+ }
168
+
169
+ /// Make sure we do not have bad enum layout optimizations.
170
+ fn rust_issue_68303 ( ) {
171
+ let optional = Some ( RefCell :: new ( false ) ) ;
172
+ let mut handle = optional. as_ref ( ) . unwrap ( ) . borrow_mut ( ) ;
173
+ assert ! ( optional. is_some( ) ) ;
174
+ * handle = true ;
175
+ }
0 commit comments