@@ -10,6 +10,8 @@ fn main() {
1010 aliasing_read_only_mutable_refs ( ) ;
1111 string_as_mut_ptr ( ) ;
1212 two_mut_protected_same_alloc ( ) ;
13+ direct_mut_to_const_raw ( ) ;
14+ local_addr_of_mut ( ) ;
1315
1416 // Stacked Borrows tests
1517 read_does_not_invalidate1 ( ) ;
@@ -19,7 +21,6 @@ fn main() {
1921 mut_raw_mut ( ) ;
2022 partially_invalidate_mut ( ) ;
2123 drop_after_sharing ( ) ;
22- direct_mut_to_const_raw ( ) ;
2324 two_raw ( ) ;
2425 shr_and_raw ( ) ;
2526 disjoint_mutable_subborrows ( ) ;
@@ -28,6 +29,18 @@ fn main() {
2829 mut_below_shr ( ) ;
2930 wide_raw_ptr_in_tuple ( ) ;
3031 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 } ;
3144}
3245
3346// Tree Borrows has no issue with several mutable references existing
@@ -172,12 +185,12 @@ fn drop_after_sharing() {
172185
173186// Make sure that coercing &mut T to *const T produces a writeable pointer.
174187fn 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 ;
177189 let y: * const i32 = x;
178- unsafe { *(y as *mut i32) = 1; }
190+ unsafe {
191+ * ( y as * mut i32 ) = 1 ;
192+ }
179193 assert_eq ! ( * x, 1 ) ;
180- */
181194}
182195
183196// 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() {
298311 drop ( unsafe { Box :: from_raw ( raw) } ) ;
299312 } ) ;
300313}
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