Skip to content

Commit

Permalink
Auto merge of #44811 - zilbuz:issue-44596/E0506, r=arielb1
Browse files Browse the repository at this point in the history
MIR-borrowck: Adding notes to E0506

This PR adds notes to the MIR borrowck error E0506.

Part of #44596
  • Loading branch information
bors committed Sep 29, 2017
2 parents 46ef620 + b683538 commit a379780
Show file tree
Hide file tree
Showing 14 changed files with 162 additions and 40 deletions.
15 changes: 12 additions & 3 deletions src/librustc_mir/borrow_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
WriteKind::StorageDead |
WriteKind::Mutate =>
this.report_illegal_mutation_of_borrowed(
context, lvalue_span),
context, lvalue_span, borrow),
WriteKind::Move =>
this.report_move_out_while_borrowed(
context, lvalue_span, borrow),
Expand Down Expand Up @@ -987,10 +987,19 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
err.emit();
}

fn report_illegal_mutation_of_borrowed(&mut self, _: Context, (lvalue, span): (&Lvalue, Span)) {
fn report_illegal_mutation_of_borrowed(&mut self,
_: Context,
(lvalue, span): (&Lvalue, Span),
loan: &BorrowData) {
let describe_lvalue = self.describe_lvalue(lvalue);
let borrow_span = self.retrieve_borrow_span(loan);

let mut err = self.tcx.cannot_assign_to_borrowed(
span, &self.describe_lvalue(lvalue), Origin::Mir);
// FIXME: add span labels for borrow and assignment points

err.span_label(borrow_span, format!("borrow of `{}` occurs here", describe_lvalue));
err.span_label(span, format!("assignment to borrowed `{}` occurs here", describe_lvalue));

err.emit();
}

Expand Down
7 changes: 6 additions & 1 deletion src/test/compile-fail/E0506.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// revisions: ast mir
//[mir]compile-flags: -Z emit-end-regions -Z borrowck-mir

struct FancyNum {
num: u8,
}

fn main() {
let mut fancy_num = FancyNum { num: 5 };
let fancy_ref = &fancy_num;
fancy_num = FancyNum { num: 6 }; //~ ERROR E0506
fancy_num = FancyNum { num: 6 }; //[ast]~ ERROR E0506
//[mir]~^ ERROR (Mir) [E0506]
//[mir]~| ERROR (Ast) [E0506]

println!("Num: {}, Ref: {}", fancy_num.num, fancy_ref.num);
}
15 changes: 12 additions & 3 deletions src/test/compile-fail/borrowck/borrowck-assign-comp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 emit-end-regions -Z borrowck-mir

struct point { x: isize, y: isize }

fn a() {
Expand All @@ -17,7 +20,9 @@ fn a() {
// This assignment is illegal because the field x is not
// inherently mutable; since `p` was made immutable, `p.x` is now
// immutable. Otherwise the type of &_q.x (&isize) would be wrong.
p.x = 5; //~ ERROR cannot assign to `p.x`
p.x = 5; //[ast]~ ERROR cannot assign to `p.x`
//[mir]~^ ERROR cannot assign to `p.x` because it is borrowed (Ast)
//[mir]~| ERROR cannot assign to `p.0` because it is borrowed (Mir)
q.x;
}

Expand All @@ -27,7 +32,9 @@ fn c() {

let mut p = point {x: 3, y: 4};
let q = &p.y;
p = point {x: 5, y: 7};//~ ERROR cannot assign to `p`
p = point {x: 5, y: 7};//[ast]~ ERROR cannot assign to `p`
//[mir]~^ ERROR cannot assign to `p` because it is borrowed (Ast)
//[mir]~| ERROR cannot assign to `p` because it is borrowed (Mir)
p.x; // silence warning
*q; // stretch loan
}
Expand All @@ -38,7 +45,9 @@ fn d() {

let mut p = point {x: 3, y: 4};
let q = &p.y;
p.y = 5; //~ ERROR cannot assign to `p.y`
p.y = 5; //[ast]~ ERROR cannot assign to `p.y`
//[mir]~^ ERROR cannot assign to `p.y` because it is borrowed (Ast)
//[mir]~| ERROR cannot assign to `p.1` because it is borrowed (Mir)
*q;
}

Expand Down
36 changes: 28 additions & 8 deletions src/test/compile-fail/borrowck/borrowck-closures-mut-and-imm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
// Tests that two closures cannot simultaneously have mutable
// and immutable access to the variable. Issue #6801.

// ignore-tidy-linelength
// revisions: ast mir
//[mir]compile-flags: -Z emit-end-regions -Z borrowck-mir

#![feature(box_syntax)]

fn get(x: &isize) -> isize {
Expand All @@ -24,37 +28,49 @@ fn set(x: &mut isize) {
fn a() {
let mut x = 3;
let c1 = || x = 4;
let c2 = || x * 5; //~ ERROR cannot borrow `x`
let c2 = || x * 5; //[ast]~ ERROR cannot borrow `x`
//[mir]~^ ERROR cannot borrow `x` as immutable because it is also borrowed as mutable (Ast)
//[mir]~| ERROR cannot borrow `x` as immutable because it is also borrowed as mutable (Mir)
}

fn b() {
let mut x = 3;
let c1 = || set(&mut x);
let c2 = || get(&x); //~ ERROR cannot borrow `x`
let c2 = || get(&x); //[ast]~ ERROR cannot borrow `x`
//[mir]~^ ERROR cannot borrow `x` as immutable because it is also borrowed as mutable (Ast)
//[mir]~| ERROR cannot borrow `x` as immutable because it is also borrowed as mutable (Mir)
}

fn c() {
let mut x = 3;
let c1 = || set(&mut x);
let c2 = || x * 5; //~ ERROR cannot borrow `x`
let c2 = || x * 5; //[ast]~ ERROR cannot borrow `x`
//[mir]~^ ERROR cannot borrow `x` as immutable because it is also borrowed as mutable (Ast)
//[mir]~| ERROR cannot borrow `x` as immutable because it is also borrowed as mutable (Mir)
}

fn d() {
let mut x = 3;
let c2 = || x * 5;
x = 5; //~ ERROR cannot assign
x = 5; //[ast]~ ERROR cannot assign
//[mir]~^ ERROR cannot assign to `x` because it is borrowed (Ast)
//[mir]~| ERROR cannot assign to `x` because it is borrowed (Mir)
}

fn e() {
let mut x = 3;
let c1 = || get(&x);
x = 5; //~ ERROR cannot assign
x = 5; //[ast]~ ERROR cannot assign
//[mir]~^ ERROR cannot assign to `x` because it is borrowed (Ast)
//[mir]~| ERROR cannot assign to `x` because it is borrowed (Mir)
}

fn f() {
let mut x: Box<_> = box 3;
let c1 = || get(&*x);
*x = 5; //~ ERROR cannot assign
*x = 5; //[ast]~ ERROR cannot assign
//[mir]~^ ERROR cannot assign to `*x` because it is borrowed (Ast)
//[mir]~| ERROR cannot assign to `(*x)` because it is borrowed (Mir)
}

fn g() {
Expand All @@ -64,7 +80,9 @@ fn g() {

let mut x: Box<_> = box Foo { f: box 3 };
let c1 = || get(&*x.f);
*x.f = 5; //~ ERROR cannot assign to `*x.f`
*x.f = 5; //[ast]~ ERROR cannot assign to `*x.f`
//[mir]~^ ERROR cannot assign to `*x.f` because it is borrowed (Ast)
//[mir]~| ERROR cannot assign to `(*(*x).0)` because it is borrowed (Mir)
}

fn h() {
Expand All @@ -74,7 +92,9 @@ fn h() {

let mut x: Box<_> = box Foo { f: box 3 };
let c1 = || get(&*x.f);
let c2 = || *x.f = 5; //~ ERROR cannot borrow `x` as mutable
let c2 = || *x.f = 5; //[ast]~ ERROR cannot borrow `x` as mutable
//[mir]~^ ERROR cannot borrow `x` as mutable because it is also borrowed as immutable (Ast)
//[mir]~| ERROR cannot borrow `x` as mutable because it is also borrowed as immutable (Mir)
}

fn main() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// revisions: ast mir
//[mir]compile-flags: -Z emit-end-regions -Z borrowck-mir

fn main() {
let mut _a = 3;
let _b = &mut _a;
{
let _c = &*_b;
_a = 4; //~ ERROR cannot assign to `_a`
_a = 4; //[ast]~ ERROR cannot assign to `_a`
//[mir]~^ ERROR cannot assign to `_a` because it is borrowed (Ast)
//[mir]~| ERROR cannot assign to `_a` because it is borrowed (Mir)
}
}
7 changes: 6 additions & 1 deletion src/test/compile-fail/borrowck/borrowck-lend-flow-match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 emit-end-regions -Z borrowck-mir

#![allow(unused_variables)]
#![allow(unused_assignments)]

Expand All @@ -22,7 +25,9 @@ fn separate_arms() {
x = Some(0);
}
Some(ref __isize) => {
x = Some(1); //~ ERROR cannot assign
x = Some(1); //[ast]~ ERROR cannot assign
//[mir]~^ ERROR cannot assign to `x` because it is borrowed (Ast)
//[mir]~| ERROR cannot assign to `x` because it is borrowed (Mir)
}
}
x.clone(); // just to prevent liveness warnings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
// operator. The accounting of the all the implicit things going on
// here is rather subtle. Issue #20232.

// revisions: ast mir
//[mir]compile-flags: -Z emit-end-regions -Z borrowck-mir

use std::ops::{Deref, Index};

struct MyVec<T> { x: T }
Expand All @@ -39,7 +42,9 @@ fn main() {
let mut v = MyVec { x: MyPtr { x: Foo { f: 22 } } };
let i = &v[0].f;
v = MyVec { x: MyPtr { x: Foo { f: 23 } } };
//~^ ERROR cannot assign to `v`
//[ast]~^ ERROR cannot assign to `v`
//[mir]~^^ ERROR cannot assign to `v` because it is borrowed (Ast)
//[mir]~| ERROR cannot assign to `v` because it is borrowed (Mir)
read(*i);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 emit-end-regions -Z borrowck-mir

fn main() {
let mut x: Option<isize> = None;
match x {
Expand All @@ -17,7 +20,9 @@ fn main() {
}
Some(ref i) => {
// But on this branch, `i` is an outstanding borrow
x = Some(*i+1); //~ ERROR cannot assign to `x`
x = Some(*i+1); //[ast]~ ERROR cannot assign to `x`
//[mir]~^ ERROR cannot assign to `x` because it is borrowed (Ast)
//[mir]~| ERROR cannot assign to `x` because it is borrowed (Mir)
}
}
x.clone(); // just to prevent liveness warnings
Expand Down
50 changes: 38 additions & 12 deletions src/test/compile-fail/borrowck/borrowck-union-borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
// except according to those terms.

// ignore-tidy-linelength
// revisions: ast mir
//[mir]compile-flags: -Z emit-end-regions -Z borrowck-mir

#[derive(Clone, Copy)]
union U {
Expand All @@ -30,11 +32,15 @@ fn main() {
}
{
let ra = &u.a;
let rma = &mut u.a; //~ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable
let rma = &mut u.a; //[ast]~ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable
//[mir]~^ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable (Ast)
//[mir]~| ERROR cannot borrow `u.0` as mutable because it is also borrowed as immutable (Mir)
}
{
let ra = &u.a;
u.a = 1; //~ ERROR cannot assign to `u.a` because it is borrowed
u.a = 1; //[ast]~ ERROR cannot assign to `u.a` because it is borrowed
//[mir]~^ ERROR cannot assign to `u.a` because it is borrowed (Ast)
//[mir]~| ERROR cannot assign to `u.0` because it is borrowed (Mir)
}
// Imm borrow, other field
{
Expand All @@ -47,45 +53,65 @@ fn main() {
}
{
let ra = &u.a;
let rmb = &mut u.b; //~ ERROR cannot borrow `u` (via `u.b`) as mutable because `u` is also borrowed as immutable (via `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`)
//[mir]~^ ERROR cannot borrow `u` (via `u.b`) as mutable because `u` is also borrowed as immutable (via `u.a`) (Ast)
// FIXME Error for MIR (needs support for union)
}
{
let ra = &u.a;
u.b = 1; //~ ERROR cannot assign to `u.b` because it is borrowed
u.b = 1; //[ast]~ ERROR cannot assign to `u.b` because it is borrowed
//[mir]~^ ERROR cannot assign to `u.b` because it is borrowed (Ast)
// FIXME Error for MIR (needs support for union)
}
// Mut borrow, same field
{
let rma = &mut u.a;
let ra = &u.a; //~ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable
let ra = &u.a; //[ast]~ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable
//[mir]~^ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable (Ast)
//[mir]~| ERROR cannot borrow `u.0` as immutable because it is also borrowed as mutable (Mir)
}
{
let ra = &mut u.a;
let a = u.a; //~ ERROR cannot use `u.a` because it was mutably borrowed
let a = u.a; //[ast]~ ERROR cannot use `u.a` because it was mutably borrowed
//[mir]~^ ERROR cannot use `u.a` because it was mutably borrowed (Ast)
//[mir]~| ERROR cannot use `u.0` because it was mutably borrowed (Mir)
}
{
let rma = &mut u.a;
let rma2 = &mut u.a; //~ ERROR cannot borrow `u.a` as mutable more than once at a time
let rma2 = &mut u.a; //[ast]~ ERROR cannot borrow `u.a` as mutable more than once at a time
//[mir]~^ ERROR cannot borrow `u.a` as mutable more than once at a time (Ast)
//[mir]~| ERROR cannot borrow `u.0` as mutable more than once at a time (Mir)
}
{
let rma = &mut u.a;
u.a = 1; //~ ERROR cannot assign to `u.a` because it is borrowed
u.a = 1; //[ast]~ ERROR cannot assign to `u.a` because it is borrowed
//[mir]~^ ERROR cannot assign to `u.a` because it is borrowed (Ast)
//[mir]~| ERROR cannot assign to `u.0` because it is borrowed (Mir)
}
// Mut borrow, other field
{
let rma = &mut u.a;
let rb = &u.b; //~ ERROR cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `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`)
//[mir]~^ ERROR cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `u.a`) (Ast)
// FIXME Error for MIR (needs support for union)
}
{
let ra = &mut u.a;
let b = u.b; //~ ERROR cannot use `u.b` because it was mutably borrowed
let b = u.b; //[ast]~ ERROR cannot use `u.b` because it was mutably borrowed
//[mir]~^ ERROR cannot use `u.b` because it was mutably borrowed (Ast)
// FIXME Error for MIR (needs support for union)
}
{
let rma = &mut u.a;
let rmb2 = &mut u.b; //~ ERROR cannot borrow `u` (via `u.b`) as mutable more than once at a time
let rmb2 = &mut u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as mutable more than once at a time
//[mir]~^ ERROR cannot borrow `u` (via `u.b`) as mutable more than once at a time (Ast)
// FIXME Error for MIR (needs support for union)
}
{
let rma = &mut u.a;
u.b = 1; //~ ERROR cannot assign to `u.b` because it is borrowed
u.b = 1; //[ast]~ ERROR cannot assign to `u.b` because it is borrowed
//[mir]~^ ERROR cannot assign to `u.b` because it is borrowed (Ast)
// FIXME Error for MIR (needs support for union)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 emit-end-regions -Z borrowck-mir

#![feature(slice_patterns)]

fn main() {
Expand All @@ -17,7 +20,9 @@ fn main() {
_ => unreachable!()
};
println!("t[0]: {}", t[0]);
a[2] = 0; //~ ERROR cannot assign to `a[..]` because it is borrowed
a[2] = 0; //[ast]~ ERROR cannot assign to `a[..]` because it is borrowed
//[mir]~^ ERROR cannot assign to `a[..]` because it is borrowed (Ast)
// FIXME Error for MIR (error missed)
println!("t[0]: {}", t[0]);
t[0];
}
Loading

0 comments on commit a379780

Please sign in to comment.