1+ // compile-flags: -Zmiri-track-raw-pointers
2+ // ignore-windows (FIXME: tracking raw pointers does not work on Windows)
3+ #![ feature( raw_ref_macros) ]
4+ use std:: ptr;
5+
16// Test various stacked-borrows-related things.
27fn main ( ) {
38 read_does_not_invalidate1 ( ) ;
49 read_does_not_invalidate2 ( ) ;
5- ref_raw_int_raw ( ) ;
610 mut_raw_then_mut_shr ( ) ;
711 mut_shr_then_mut_raw ( ) ;
812 mut_raw_mut ( ) ;
@@ -12,6 +16,7 @@ fn main() {
1216 two_raw ( ) ;
1317 shr_and_raw ( ) ;
1418 disjoint_mutable_subborrows ( ) ;
19+ raw_ref_to_part ( ) ;
1520}
1621
1722// Make sure that reading from an `&mut` does, like reborrowing to `&`,
@@ -37,16 +42,6 @@ fn read_does_not_invalidate2() {
3742 assert_eq ! ( * foo( & mut ( 1 , 2 ) ) , 2 ) ;
3843}
3944
40- // Just to make sure that casting a ref to raw, to int and back to raw
41- // and only then using it works. This rules out ideas like "do escape-to-raw lazily";
42- // after casting to int and back, we lost the tag that could have let us do that.
43- fn ref_raw_int_raw ( ) {
44- let mut x = 3 ;
45- let xref = & mut x;
46- let xraw = xref as * mut i32 as usize as * mut i32 ;
47- assert_eq ! ( unsafe { * xraw } , 3 ) ;
48- }
49-
5045// Escape a mut to raw, then share the same mut and use the share, then the raw.
5146// That should work.
5247fn mut_raw_then_mut_shr ( ) {
@@ -162,3 +157,22 @@ fn disjoint_mutable_subborrows() {
162157 a. push_str ( " world" ) ;
163158 eprintln ! ( "{:?} {:?}" , a, b) ;
164159}
160+
161+ fn raw_ref_to_part ( ) {
162+ struct Part {
163+ _lame : i32 ,
164+ }
165+
166+ #[ repr( C ) ]
167+ struct Whole {
168+ part : Part ,
169+ extra : i32 ,
170+ }
171+
172+ let it = Box :: new ( Whole { part : Part { _lame : 0 } , extra : 42 } ) ;
173+ let whole = ptr:: raw_mut!( * Box :: leak( it) ) ;
174+ let part = unsafe { ptr:: raw_mut!( ( * whole) . part) } ;
175+ let typed = unsafe { & mut * ( part as * mut Whole ) } ;
176+ assert ! ( typed. extra == 42 ) ;
177+ drop ( unsafe { Box :: from_raw ( whole) } ) ;
178+ }
0 commit comments