@@ -10,6 +10,8 @@ fn main() {
10
10
aliasing_read_only_mutable_refs ( ) ;
11
11
string_as_mut_ptr ( ) ;
12
12
two_mut_protected_same_alloc ( ) ;
13
+ direct_mut_to_const_raw ( ) ;
14
+ local_addr_of_mut ( ) ;
13
15
14
16
// Stacked Borrows tests
15
17
read_does_not_invalidate1 ( ) ;
@@ -19,7 +21,6 @@ fn main() {
19
21
mut_raw_mut ( ) ;
20
22
partially_invalidate_mut ( ) ;
21
23
drop_after_sharing ( ) ;
22
- direct_mut_to_const_raw ( ) ;
23
24
two_raw ( ) ;
24
25
shr_and_raw ( ) ;
25
26
disjoint_mutable_subborrows ( ) ;
@@ -28,6 +29,18 @@ fn main() {
28
29
mut_below_shr ( ) ;
29
30
wide_raw_ptr_in_tuple ( ) ;
30
31
not_unpin_not_protected ( ) ;
32
+ write_does_not_invalidate_all_aliases ( ) ;
33
+ }
34
+
35
+ #[ allow( unused_assignments) ]
36
+ fn local_addr_of_mut ( ) {
37
+ let mut local = 0 ;
38
+ let ptr = ptr:: addr_of_mut!( local) ;
39
+ // In SB, `local` and `*ptr` would have different tags, but in TB they have the same tag.
40
+ local = 1 ;
41
+ unsafe { * ptr = 2 } ;
42
+ local = 3 ;
43
+ unsafe { * ptr = 4 } ;
31
44
}
32
45
33
46
// Tree Borrows has no issue with several mutable references existing
@@ -172,12 +185,12 @@ fn drop_after_sharing() {
172
185
173
186
// Make sure that coercing &mut T to *const T produces a writeable pointer.
174
187
fn direct_mut_to_const_raw ( ) {
175
- // TODO: This is currently disabled, waiting on a decision on <https://github.com/rust-lang/rust/issues/56604>
176
- /*let x = &mut 0;
188
+ let x = & mut 0 ;
177
189
let y: * const i32 = x;
178
- unsafe { *(y as *mut i32) = 1; }
190
+ unsafe {
191
+ * ( y as * mut i32 ) = 1 ;
192
+ }
179
193
assert_eq ! ( * x, 1 ) ;
180
- */
181
194
}
182
195
183
196
// Make sure that we can create two raw pointers from a mutable reference and use them both.
@@ -298,3 +311,31 @@ fn not_unpin_not_protected() {
298
311
drop ( unsafe { Box :: from_raw ( raw) } ) ;
299
312
} ) ;
300
313
}
314
+
315
+ fn write_does_not_invalidate_all_aliases ( ) {
316
+ // In TB there are other ways to do that (`addr_of!(*x)` has the same tag as `x`),
317
+ // but let's still make sure this SB test keeps working.
318
+
319
+ mod other {
320
+ /// Some private memory to store stuff in.
321
+ static mut S : * mut i32 = 0 as * mut i32 ;
322
+
323
+ pub fn lib1 ( x : & & mut i32 ) {
324
+ unsafe {
325
+ S = ( x as * const & mut i32 ) . cast :: < * mut i32 > ( ) . read ( ) ;
326
+ }
327
+ }
328
+
329
+ pub fn lib2 ( ) {
330
+ unsafe {
331
+ * S = 1337 ;
332
+ }
333
+ }
334
+ }
335
+
336
+ let x = & mut 0 ;
337
+ other:: lib1 ( & x) ;
338
+ * x = 42 ; // a write to x -- invalidates other pointers?
339
+ other:: lib2 ( ) ;
340
+ assert_eq ! ( * x, 1337 ) ; // oops, the value changed! I guess not all pointers were invalidated
341
+ }
0 commit comments