Auto merge of #46268 - arielb1:union-borrow, r=nikomatsakis

MIR borrowck: implement union-and-array-compatible semantics

Fixes #44831.
Fixes #44834.
Fixes #45537.
Fixes #45696 (by implementing DerefPure semantics, which is what we want going forward).

r? @nikomatsakis
This commit is contained in:
bors 2017-12-06 18:30:15 +00:00
commit cf30759a84
17 changed files with 608 additions and 176 deletions

View file

@ -13,7 +13,7 @@
fn cplusplus_mode(x: isize) -> &'static isize {
&x //[ast]~ ERROR `x` does not live long enough
//[mir]~^ ERROR borrowed value does not live long enough
}
//[mir]~^ ERROR borrowed value does not live long enough
fn main() {}

View file

@ -14,9 +14,9 @@
fn cplusplus_mode_exceptionally_unsafe(x: &mut Option<&'static mut isize>) {
let mut z = (0, 0);
*x = Some(&mut z.1); //[ast]~ ERROR [E0597]
//[mir]~^ ERROR [E0597]
panic!("catch me for a dangling pointer!")
}
//[mir]~^ ERROR [E0597]
fn main() {
cplusplus_mode_exceptionally_unsafe(&mut None);

View file

@ -8,6 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// revisions: ast mir
//[mir]compile-flags: -Z borrowck=mir
#![feature(box_syntax)]
fn call_f<F:FnOnce() -> isize>(f: F) -> isize {
@ -18,5 +21,6 @@ fn main() {
let t: Box<_> = box 3;
call_f(move|| { *t + 1 });
call_f(move|| { *t + 1 }); //~ ERROR capture of moved value
call_f(move|| { *t + 1 }); //[ast]~ ERROR capture of moved value
//[mir]~^ ERROR use of moved value
}

View file

@ -23,15 +23,9 @@ fn main() {
1 => { addr = &mut x; } //[ast]~ ERROR [E0499]
//[mir]~^ ERROR [E0499]
2 => { addr = &mut x; } //[ast]~ ERROR [E0499]
//[mir]~^ ERROR [E0506]
//[mir]~| ERROR [E0499]
//[mir]~| ERROR [E0499]
//[mir]~^ ERROR [E0499]
_ => { addr = &mut x; } //[ast]~ ERROR [E0499]
//[mir]~^ ERROR [E0506]
//[mir]~| ERROR [E0499]
//[mir]~| ERROR [E0499]
//[mir]~^ ERROR [E0499]
}
}
}

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// ignore-test will be fixed later
// revisions: ast mir
//[mir]compile-flags: -Z borrowck=mir

View file

@ -52,12 +52,12 @@ fn main() {
{
let ra = &u.a;
let rmb = &mut u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as mutable because `u` is also borrowed as immutable (via `u.a`)
// FIXME Error for MIR (needs support for union)
//[mir]~^ ERROR cannot borrow `u.b` as mutable because it is also borrowed as immutable
}
{
let ra = &u.a;
u.b = 1; //[ast]~ ERROR cannot assign to `u.b` because it is borrowed
// FIXME Error for MIR (needs support for union)
//[mir]~^ ERROR cannot assign to `u.b` because it is borrowed
}
// Mut borrow, same field
{
@ -84,22 +84,23 @@ fn main() {
{
let rma = &mut u.a;
let rb = &u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `u.a`)
// FIXME Error for MIR (needs support for union)
//[mir]~^ ERROR cannot borrow `u.b` as immutable because it is also borrowed as mutable
}
{
let ra = &mut u.a;
let b = u.b; //[ast]~ ERROR cannot use `u.b` because it was mutably borrowed
// FIXME Error for MIR (needs support for union)
//[mir]~^ ERROR cannot use `u.b` because it was mutably borrowed
}
{
let rma = &mut u.a;
let rmb2 = &mut u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as mutable more than once at a time
// FIXME Error for MIR (needs support for union)
//[mir]~^ ERROR cannot borrow `u.b` as mutable more than once at a time
}
{
let rma = &mut u.a;
u.b = 1; //[ast]~ ERROR cannot assign to `u.b` because it is borrowed
// FIXME Error for MIR (needs support for union)
//[mir]~^ ERROR cannot assign to `u.b` because it is borrowed
}
}
}

View file

@ -1,3 +1,4 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
@ -22,7 +23,7 @@ fn main() {
println!("t[0]: {}", t[0]);
a[2] = 0; //[ast]~ ERROR cannot assign to `a[..]` because it is borrowed
//[cmp]~^ ERROR cannot assign to `a[..]` because it is borrowed (Ast)
// FIXME Error for MIR (error missed)
//[cmp]~| ERROR cannot assign to `a[..]` because it is borrowed (Mir)
println!("t[0]: {}", t[0]);
t[0];
}

View file

@ -20,13 +20,9 @@ fn causes_ice(mut l: &mut Sexpression) {
loop { match l {
&mut Sexpression::Num(ref mut n) => {},
&mut Sexpression::Cons(ref mut expr) => { //[ast]~ ERROR [E0499]
//[mir]~^ ERROR [E0506]
//[mir]~| ERROR [E0499]
//[mir]~^ ERROR [E0499]
l = &mut **expr; //[ast]~ ERROR [E0506]
//[mir]~^ ERROR [E0506]
//[mir]~| ERROR [E0506]
//[mir]~| ERROR [E0499]
//[mir]~| ERROR [E0499]
}
}}
}

View file

@ -16,6 +16,10 @@
// behavior (because the improperly accepted closure was actually
// able to be invoked).
// ignore-tidy-linelength
// revisions: ast mir
//[mir]compile-flags: -Z borrowck=mir
struct WrapA<F>(Option<F>);
impl<F> WrapA<F> {
@ -75,9 +79,11 @@ impl<F, T> WrapA<F>
fn main() {
let mut w = WrapA::new().set(|x: usize, y: usize| {
WrapB::new().set(|t: bool| if t { x } else { y }) // (separate errors for `x` vs `y`)
//~^ ERROR `x` does not live long enough
//~| ERROR `y` does not live long enough
//[ast]~^ ERROR `x` does not live long enough
//[ast]~| ERROR `y` does not live long enough
});
//[mir]~^ ERROR borrowed value does not live long enough
//[mir]~| ERROR borrowed value does not live long enough
w.handle(); // This works
// w.handle_ref(); // This doesn't

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: -Z borrowck=compare
fn test1() {
// from issue 6338