diff --git a/tests/compile-fail/stacked_borrows/shared_rw_borrows_are_weak1.rs b/tests/compile-fail/stacked_borrows/shared_rw_borrows_are_weak1.rs new file mode 100644 index 0000000000..d734caf1d9 --- /dev/null +++ b/tests/compile-fail/stacked_borrows/shared_rw_borrows_are_weak1.rs @@ -0,0 +1,14 @@ +// We want to test that granting a SharedReadWrite will be added +// *below* an already granted Unique -- so writing to +// the SharedReadWrite will invalidate the Unique. + +use std::mem; +use std::cell::Cell; + +fn main() { unsafe { + let x = &mut Cell::new(0); + let y: &mut Cell = mem::transmute(&mut *x); // launder lifetime + let shr_rw = &*x; // thanks to interior mutability this will be a SharedReadWrite + shr_rw.set(1); + y.get_mut(); //~ ERROR borrow stack +} } diff --git a/tests/compile-fail/stacked_borrows/shared_rw_borrows_are_weak2.rs b/tests/compile-fail/stacked_borrows/shared_rw_borrows_are_weak2.rs new file mode 100644 index 0000000000..942bb503db --- /dev/null +++ b/tests/compile-fail/stacked_borrows/shared_rw_borrows_are_weak2.rs @@ -0,0 +1,14 @@ +// We want to test that granting a SharedReadWrite will be added +// *below* an already granted SharedReadWrite -- so writing to +// the SharedReadWrite will invalidate the SharedReadWrite. + +use std::mem; +use std::cell::RefCell; + +fn main() { unsafe { + let x = &mut RefCell::new(0); + let y: &i32 = mem::transmute(&*x.borrow()); // launder lifetime + let shr_rw = &*x; // thanks to interior mutability this will be a SharedReadWrite + shr_rw.replace(1); + let _val = *y; //~ ERROR borrow stack +} } diff --git a/tests/run-pass/stacked-borrows/stacked-borrows.rs b/tests/run-pass/stacked-borrows/stacked-borrows.rs index 791e97f0eb..7d84e33b3d 100644 --- a/tests/run-pass/stacked-borrows/stacked-borrows.rs +++ b/tests/run-pass/stacked-borrows/stacked-borrows.rs @@ -11,6 +11,7 @@ fn main() { drop_after_sharing(); direct_mut_to_const_raw(); two_raw(); + shr_and_raw(); } // Deref a raw ptr to access a field of a large struct, where the field @@ -136,3 +137,15 @@ fn two_raw() { unsafe { *y1 += 2; *y2 += 1; } } + +// Make sure that creating a *mut does not invalidate existing shared references. +fn shr_and_raw() { /* unsafe { + use std::mem; + // FIXME: This is currently disabled because "as *mut _" incurs a reborrow. + let x = &mut 0; + let y1: &i32 = mem::transmute(&*x); // launder lifetimes + let y2 = x as *mut _; + let _val = *y1; + *y2 += 1; + // TODO: Once this works, add compile-fail test that tries to read from y1 again. +} */ }