diff options
| author | Felix S. Klock II <pnkfelix@pnkfx.org> | 2017-12-07 17:45:13 +0100 |
|---|---|---|
| committer | Felix S. Klock II <pnkfelix@pnkfx.org> | 2017-12-13 15:48:21 -0600 |
| commit | 5cae7a046922375352ca1ee33ae00df2123972ad (patch) | |
| tree | 39a8b73704a310309342282c7cf6a888403f2b52 /src/test/compile-fail | |
| parent | 18aedf6b23db6f409f8d3073ab0c8ca923e9b141 (diff) | |
| download | rust-5cae7a046922375352ca1ee33ae00df2123972ad.tar.gz rust-5cae7a046922375352ca1ee33ae00df2123972ad.zip | |
Check activation points as the place where mutable borrows become relevant.
Since we are now checking activation points, I removed one of the checks at the reservation point. (You can see the effect this had on two-phase-reservation-sharing-interference-2.rs) Also, since we now have checks at both the reservation point and the activation point, we sometimes would observe duplicate errors (since either one independently interferes with another mutable borrow). To deal with this, I used a similar strategy to one used as discussed on issue #45360: keep a set of errors reported (in this case for reservations), and then avoid doing the checks for the corresponding activations. (This does mean that some errors could get masked, namely for conflicting borrows that start after the reservation but still conflict with the activation, which is unchecked when there was an error for the reservation. But this seems like a reasonable price to pay.)
Diffstat (limited to 'src/test/compile-fail')
| -rw-r--r-- | src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs | 62 | ||||
| -rw-r--r-- | src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference-2.rs | 21 |
2 files changed, 72 insertions, 11 deletions
diff --git a/src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs b/src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs new file mode 100644 index 00000000000..b6f5e17f1f6 --- /dev/null +++ b/src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs @@ -0,0 +1,62 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// revisions: lxl nll +//[lxl]compile-flags: -Z borrowck=mir -Z two-phase-borrows +//[nll]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll + +// This is an important corner case pointed out by Niko: one is +// allowed to initiate a shared borrow during a reservation, but it +// *must end* before the activation occurs. +// +// FIXME: for clarity, diagnostics for these cases might be better off +// if they specifically said "cannot activate mutable borrow of `x`" + +#![allow(dead_code)] + +fn read(_: &i32) { } + +fn ok() { + let mut x = 3; + let y = &mut x; + { let z = &x; read(z); } + *y += 1; +} + +fn not_ok() { + let mut x = 3; + let y = &mut x; + let z = &x; + *y += 1; + //[lxl]~^ ERROR cannot borrow `x` as mutable because it is also borrowed as immutable + //[nll]~^^ ERROR cannot borrow `x` as mutable because it is also borrowed as immutable + read(z); +} + +fn should_be_ok_with_nll() { + let mut x = 3; + let y = &mut x; + let z = &x; + read(z); + *y += 1; + //[lxl]~^ ERROR cannot borrow `x` as mutable because it is also borrowed as immutable + // (okay with nll today) +} + +fn should_also_eventually_be_ok_with_nll() { + let mut x = 3; + let y = &mut x; + let _z = &x; + *y += 1; + //[lxl]~^ ERROR cannot borrow `x` as mutable because it is also borrowed as immutable + //[nll]~^^ ERROR cannot borrow `x` as mutable because it is also borrowed as immutable +} + +fn main() { } diff --git a/src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference-2.rs b/src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference-2.rs index 397b3dafa7d..fc9100c8a9a 100644 --- a/src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference-2.rs +++ b/src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference-2.rs @@ -15,24 +15,23 @@ // This is similar to two-phase-reservation-sharing-interference.rs // in that it shows a reservation that overlaps with a shared borrow. // -// However, it is also more immediately concerning because one would -// intutively think that if run-pass/borrowck/two-phase-baseline.rs -// works, then this *should* work too. +// Currently, this test fails with lexical lifetimes, but succeeds +// with non-lexical lifetimes. (The reason is because the activation +// of the mutable borrow ends up overlapping with a lexically-scoped +// shared borrow; but a non-lexical shared borrow can end before the +// activation occurs.) // -// As before, the current implementation is (probably) more -// conservative than is necessary. -// -// So this test is just making a note of the current behavior, with -// the caveat that in the future, the rules may be loosened, at which -// point this test might be thrown out. +// So this test is just making a note of the current behavior. + +#![feature(rustc_attrs)] -fn main() { +#[rustc_error] +fn main() { //[nll]~ ERROR compilation successful let mut v = vec![0, 1, 2]; let shared = &v; v.push(shared.len()); //[lxl]~^ ERROR cannot borrow `v` as mutable because it is also borrowed as immutable [E0502] - //[nll]~^^ ERROR cannot borrow `v` as mutable because it is also borrowed as immutable [E0502] assert_eq!(v, [0, 1, 2, 3]); } |
