diff --git a/tests/compile-fail/stacked_borrows/illegal_read8.rs b/tests/compile-fail/stacked_borrows/illegal_read8.rs new file mode 100644 index 0000000000..72fca84ba1 --- /dev/null +++ b/tests/compile-fail/stacked_borrows/illegal_read8.rs @@ -0,0 +1,13 @@ +// Make sure that creating a raw ptr next to a shared ref works +// but the shared ref still gets invalidated when the raw ptr is used for writing. + +fn main() { unsafe { + use std::mem; + let x = &mut 0; + let y1: &i32 = mem::transmute(&*x); // launder lifetimes + let y2 = x as *mut _; + let _val = *y2; + let _val = *y1; + *y2 += 1; + let _fail = *y1; //~ ERROR borrow stack +} } diff --git a/tests/run-pass/stacked-borrows/stacked-borrows.rs b/tests/run-pass/stacked-borrows/stacked-borrows.rs index fe6a9a54d4..765c6188b6 100644 --- a/tests/run-pass/stacked-borrows/stacked-borrows.rs +++ b/tests/run-pass/stacked-borrows/stacked-borrows.rs @@ -108,7 +108,7 @@ fn drop_after_sharing() { // Make sure that coercing &mut T to *const T produces a writeable pointer. fn direct_mut_to_const_raw() { - // FIXME: This is currently disabled, waiting on a fix for + // TODO: This is currently disabled, waiting on a decision on /*let x = &mut 0; let y: *const i32 = x; unsafe { *(y as *mut i32) = 1; } @@ -119,9 +119,6 @@ fn direct_mut_to_const_raw() { // Make sure that we can create two raw pointers from a mutable reference and use them both. fn two_raw() { unsafe { let x = &mut 0; - // Given the implicit reborrows, the only reason this currently works is that we - // do not track raw pointers: The creation of `y2` reborrows `x` and thus pops - // `y1` off the stack. let y1 = x as *mut _; let y2 = x as *mut _; *y1 += 2; @@ -129,16 +126,14 @@ fn two_raw() { unsafe { } } // Make sure that creating a *mut does not invalidate existing shared references. -fn shr_and_raw() { /* unsafe { +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. -} */ } +} } fn disjoint_mutable_subborrows() { struct Foo { @@ -165,5 +160,5 @@ fn disjoint_mutable_subborrows() { let b = unsafe{ borrow_field_b(ptr) }; b.push(4); a.push_str(" world"); - dbg!(a,b); + eprintln!("{:?} {:?}", a, b); } diff --git a/tests/run-pass/stacked-borrows/stacked-borrows.stderr b/tests/run-pass/stacked-borrows/stacked-borrows.stderr index 4493d45ae1..8ee4e25dbe 100644 --- a/tests/run-pass/stacked-borrows/stacked-borrows.stderr +++ b/tests/run-pass/stacked-borrows/stacked-borrows.stderr @@ -1,7 +1 @@ -[$DIR/stacked-borrows.rs:168] a = "hello world" -[$DIR/stacked-borrows.rs:168] b = [ - 0, - 1, - 2, - 4, -] +"hello world" [0, 1, 2, 4]