From dbbec4d62d579ea786d53ca7eceeb4b243fb8bf1 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 6 Dec 2017 00:37:06 +0100 Subject: [PATCH] tests transcribed from nikos blog post. --- ...o-phase-allow-access-during-reservation.rs | 37 +++++++++++++++++++ .../two-phase-cannot-nest-mut-self-calls.rs | 34 +++++++++++++++++ .../compile-fail/borrowck/two-phase-sneaky.rs | 30 +++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 src/test/compile-fail/borrowck/two-phase-allow-access-during-reservation.rs create mode 100644 src/test/compile-fail/borrowck/two-phase-cannot-nest-mut-self-calls.rs create mode 100644 src/test/compile-fail/borrowck/two-phase-sneaky.rs diff --git a/src/test/compile-fail/borrowck/two-phase-allow-access-during-reservation.rs b/src/test/compile-fail/borrowck/two-phase-allow-access-during-reservation.rs new file mode 100644 index 00000000000..7695bd3e465 --- /dev/null +++ b/src/test/compile-fail/borrowck/two-phase-allow-access-during-reservation.rs @@ -0,0 +1,37 @@ +// 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 or the MIT license +// , 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 the second counter-example from Niko's blog post +// smallcultfollowing.com/babysteps/blog/2017/03/01/nested-method-calls-via-two-phase-borrowing/ +// +// It is "artificial". It is meant to illustrate directly that we +// should allow an aliasing access during reservation, but *not* while +// the mutable borrow is active. + +fn main() { + /*0*/ let mut i = 0; + + /*1*/ let p = &mut i; // (reservation of `i` starts here) + + /*2*/ let j = i; // OK: `i` is only reserved here + + /*3*/ *p += 1; // (mutable borrow of `i` starts here, since `p` is used) + + /*4*/ let k = i; //[lxl]~ ERROR cannot use `i` because it was mutably borrowed [E0503] + //[nll]~^ ERROR cannot use `i` because it was mutably borrowed [E0503] + + /*5*/ *p += 1; + + let _ = (j, k, p); +} diff --git a/src/test/compile-fail/borrowck/two-phase-cannot-nest-mut-self-calls.rs b/src/test/compile-fail/borrowck/two-phase-cannot-nest-mut-self-calls.rs new file mode 100644 index 00000000000..01b04708599 --- /dev/null +++ b/src/test/compile-fail/borrowck/two-phase-cannot-nest-mut-self-calls.rs @@ -0,0 +1,34 @@ +// 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 or the MIT license +// , 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 the third counter-example from Niko's blog post +// smallcultfollowing.com/babysteps/blog/2017/03/01/nested-method-calls-via-two-phase-borrowing/ +// +// It shows that not all nested method calls on `self` are magically +// allowed by this change. In particular, a nested `&mut` borrow is +// still disallowed. + +fn main() { + + + let mut vec = vec![0, 1]; + vec.get({ + + vec.push(2); + //[lxl]~^ ERROR cannot borrow `vec` as mutable because it is also borrowed as immutable + //[nll]~^^ ERROR cannot borrow `vec` as mutable because it is also borrowed as immutable + + 0 + }); +} diff --git a/src/test/compile-fail/borrowck/two-phase-sneaky.rs b/src/test/compile-fail/borrowck/two-phase-sneaky.rs new file mode 100644 index 00000000000..32747407c67 --- /dev/null +++ b/src/test/compile-fail/borrowck/two-phase-sneaky.rs @@ -0,0 +1,30 @@ +// 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 or the MIT license +// , 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 the first counter-example from Niko's blog post +// smallcultfollowing.com/babysteps/blog/2017/03/01/nested-method-calls-via-two-phase-borrowing/ +// of a danger for code to crash if we just turned off the check for whether +// a mutable-borrow aliases another borrow. + +fn main() { + let mut v: Vec = vec![format!("Hello, ")]; + v[0].push_str({ + + v.push(format!("foo")); + //[lxl]~^ ERROR cannot borrow `v` as mutable more than once at a time [E0499] + //[nll]~^^ ERROR cannot borrow `v` as mutable more than once at a time [E0499] + + "World!" + }); +}