Add union justifications to conflicting borrows.

This commit adds justifications to error messages for conflicting
borrows of union fields.

Where previously an error message would say
``cannot borrow `u.b` as mutable..``, it now says
``cannot borrow `u` (via `u.b`) as mutable..``.
This commit is contained in:
David Wood 2018-12-24 20:22:25 +01:00
parent 79d8a0fcef
commit 69bded2493
No known key found for this signature in database
GPG key ID: 01760B4F9F53F154
7 changed files with 141 additions and 127 deletions

View file

@ -329,10 +329,16 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
"closure" "closure"
}; };
let (desc_place, msg_place, msg_borrow) = if issued_borrow.borrowed_place == *place {
let desc_place = self.describe_place(place).unwrap_or_else(|| "_".to_owned()); let desc_place = self.describe_place(place).unwrap_or_else(|| "_".to_owned());
let tcx = self.infcx.tcx; (desc_place, "".to_string(), "".to_string())
} else {
let first_borrow_desc; let (desc_place, msg_place) = self.describe_place_for_conflicting_borrow(place);
let (_, msg_borrow) = self.describe_place_for_conflicting_borrow(
&issued_borrow.borrowed_place
);
(desc_place, msg_place, msg_borrow)
};
let explanation = self.explain_why_borrow_contains_point(context, issued_borrow, None); let explanation = self.explain_why_borrow_contains_point(context, issued_borrow, None);
let second_borrow_desc = if explanation.is_explained() { let second_borrow_desc = if explanation.is_explained() {
@ -342,6 +348,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
}; };
// FIXME: supply non-"" `opt_via` when appropriate // FIXME: supply non-"" `opt_via` when appropriate
let tcx = self.infcx.tcx;
let first_borrow_desc;
let mut err = match ( let mut err = match (
gen_borrow_kind, gen_borrow_kind,
"immutable", "immutable",
@ -355,12 +363,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
tcx.cannot_reborrow_already_borrowed( tcx.cannot_reborrow_already_borrowed(
span, span,
&desc_place, &desc_place,
"", &msg_place,
lft, lft,
issued_span, issued_span,
"it", "it",
rgt, rgt,
"", &msg_borrow,
None, None,
Origin::Mir, Origin::Mir,
) )
@ -370,12 +378,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
tcx.cannot_reborrow_already_borrowed( tcx.cannot_reborrow_already_borrowed(
span, span,
&desc_place, &desc_place,
"", &msg_place,
lft, lft,
issued_span, issued_span,
"it", "it",
rgt, rgt,
"", &msg_borrow,
None, None,
Origin::Mir, Origin::Mir,
) )
@ -386,9 +394,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
tcx.cannot_mutably_borrow_multiply( tcx.cannot_mutably_borrow_multiply(
span, span,
&desc_place, &desc_place,
"", &msg_place,
issued_span, issued_span,
"", &msg_borrow,
None, None,
Origin::Mir, Origin::Mir,
) )
@ -518,6 +526,36 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
err.buffer(&mut self.errors_buffer); err.buffer(&mut self.errors_buffer);
} }
/// Returns a description of a place and an associated message for the purposes of conflicting
/// borrow diagnostics.
///
/// If the borrow is of the field `b` of a union `u`, then the return value will be
/// `("u", " (via \`u.b\`)")`. Otherwise, for some variable `a`, the return value will be
/// `("a", "")`.
pub(super) fn describe_place_for_conflicting_borrow(
&self,
place: &Place<'tcx>,
) -> (String, String) {
place.base_local()
.filter(|local| {
// Filter out non-unions.
self.mir.local_decls[*local].ty
.ty_adt_def()
.map(|adt| adt.is_union())
.unwrap_or(false)
})
.and_then(|local| {
let desc_base = self.describe_place(&Place::Local(local))
.unwrap_or_else(|| "_".to_owned());
let desc_original = self.describe_place(place)
.unwrap_or_else(|| "_".to_owned());
return Some((desc_base, format!(" (via `{}`)", desc_original)));
})
.unwrap_or_else(|| {
(self.describe_place(place).unwrap_or_else(|| "_".to_owned()), "".to_string())
})
}
/// Reports StorageDeadOrDrop of `place` conflicts with `borrow`. /// Reports StorageDeadOrDrop of `place` conflicts with `borrow`.
/// ///
/// This means that some data referenced by `borrow` needs to live /// This means that some data referenced by `borrow` needs to live

View file

@ -1,132 +1,121 @@
error[E0502]: cannot borrow `u.a` as mutable because it is also borrowed as immutable error[E0502]: cannot borrow `u.a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-union-borrow.rs:27:23 --> $DIR/borrowck-union-borrow.rs:25:23
| |
LL | let ra = &u.a; LL | let ra = &u.a;
| ---- immutable borrow occurs here | ---- immutable borrow occurs here
LL | let rma = &mut u.a; //[ast]~ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable LL | let rma = &mut u.a; //~ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable
| ^^^^^^^^ mutable borrow occurs here | ^^^^^^^^ mutable borrow occurs here
LL | //[mir]~^ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable
LL | drop(ra); LL | drop(ra);
| -- immutable borrow later used here | -- immutable borrow later used here
error[E0506]: cannot assign to `u.a` because it is borrowed error[E0506]: cannot assign to `u.a` because it is borrowed
--> $DIR/borrowck-union-borrow.rs:33:13 --> $DIR/borrowck-union-borrow.rs:30:13
| |
LL | let ra = &u.a; LL | let ra = &u.a;
| ---- borrow of `u.a` occurs here | ---- borrow of `u.a` occurs here
LL | u.a = 1; //[ast]~ ERROR cannot assign to `u.a` because it is borrowed LL | u.a = 1; //~ ERROR cannot assign to `u.a` because it is borrowed
| ^^^^^^^ assignment to borrowed `u.a` occurs here | ^^^^^^^ assignment to borrowed `u.a` occurs here
LL | //[mir]~^ ERROR cannot assign to `u.a` because it is borrowed
LL | drop(ra); LL | drop(ra);
| -- borrow later used here | -- borrow later used here
error[E0502]: cannot borrow `u.b` as mutable because it is also borrowed as immutable error[E0502]: cannot borrow `u` (via `u.b`) as mutable because it is also borrowed as immutable (via `u.a`)
--> $DIR/borrowck-union-borrow.rs:50:23 --> $DIR/borrowck-union-borrow.rs:46:23
| |
LL | let ra = &u.a; LL | let ra = &u.a;
| ---- immutable borrow occurs here | ---- immutable borrow occurs here (via `u.a`)
LL | 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`) LL | let rmb = &mut u.b; //~ ERROR cannot borrow `u` (via `u.b`) as mutable because `u` is also borrowed as immutable (via `u.a`)
| ^^^^^^^^ mutable borrow occurs here | ^^^^^^^^ mutable borrow occurs here (via `u.b`)
LL | //[mir]~^ ERROR cannot borrow `u.b` as mutable because it is also borrowed as immutable
LL | drop(ra); LL | drop(ra);
| -- immutable borrow later used here | -- immutable borrow later used here
error[E0506]: cannot assign to `u.b` because it is borrowed error[E0506]: cannot assign to `u.b` because it is borrowed
--> $DIR/borrowck-union-borrow.rs:56:13 --> $DIR/borrowck-union-borrow.rs:51:13
| |
LL | let ra = &u.a; LL | let ra = &u.a;
| ---- borrow of `u.b` occurs here | ---- borrow of `u.b` occurs here
LL | u.b = 1; //[ast]~ ERROR cannot assign to `u.b` because it is borrowed LL | u.b = 1; //~ ERROR cannot assign to `u.b` because it is borrowed
| ^^^^^^^ assignment to borrowed `u.b` occurs here | ^^^^^^^ assignment to borrowed `u.b` occurs here
LL | //[mir]~^ ERROR cannot assign to `u.b` because it is borrowed
LL | drop(ra); LL | drop(ra);
| -- borrow later used here | -- borrow later used here
error[E0502]: cannot borrow `u.a` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `u.a` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-union-borrow.rs:63:22 --> $DIR/borrowck-union-borrow.rs:57:22
| |
LL | let rma = &mut u.a; LL | let rma = &mut u.a;
| -------- mutable borrow occurs here | -------- mutable borrow occurs here
LL | let ra = &u.a; //[ast]~ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable LL | let ra = &u.a; //~ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable
| ^^^^ immutable borrow occurs here | ^^^^ immutable borrow occurs here
LL | //[mir]~^ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable
LL | drop(rma); LL | drop(rma);
| --- mutable borrow later used here | --- mutable borrow later used here
error[E0503]: cannot use `u.a` because it was mutably borrowed error[E0503]: cannot use `u.a` because it was mutably borrowed
--> $DIR/borrowck-union-borrow.rs:69:21 --> $DIR/borrowck-union-borrow.rs:62:21
| |
LL | let ra = &mut u.a; LL | let ra = &mut u.a;
| -------- borrow of `u.a` occurs here | -------- borrow of `u.a` occurs here
LL | let a = u.a; //[ast]~ ERROR cannot use `u.a` because it was mutably borrowed LL | let a = u.a; //~ ERROR cannot use `u.a` because it was mutably borrowed
| ^^^ use of borrowed `u.a` | ^^^ use of borrowed `u.a`
LL | //[mir]~^ ERROR cannot use `u.a` because it was mutably borrowed
LL | drop(ra); LL | drop(ra);
| -- borrow later used here | -- borrow later used here
error[E0499]: cannot borrow `u.a` as mutable more than once at a time error[E0499]: cannot borrow `u.a` as mutable more than once at a time
--> $DIR/borrowck-union-borrow.rs:75:24 --> $DIR/borrowck-union-borrow.rs:67:24
| |
LL | let rma = &mut u.a; LL | let rma = &mut u.a;
| -------- first mutable borrow occurs here | -------- first mutable borrow occurs here
LL | let rma2 = &mut u.a; //[ast]~ ERROR cannot borrow `u.a` as mutable more than once at a time LL | let rma2 = &mut u.a; //~ ERROR cannot borrow `u.a` as mutable more than once at a time
| ^^^^^^^^ second mutable borrow occurs here | ^^^^^^^^ second mutable borrow occurs here
LL | //[mir]~^ ERROR cannot borrow `u.a` as mutable more than once at a time
LL | drop(rma); LL | drop(rma);
| --- first borrow later used here | --- first borrow later used here
error[E0506]: cannot assign to `u.a` because it is borrowed error[E0506]: cannot assign to `u.a` because it is borrowed
--> $DIR/borrowck-union-borrow.rs:81:13 --> $DIR/borrowck-union-borrow.rs:72:13
| |
LL | let rma = &mut u.a; LL | let rma = &mut u.a;
| -------- borrow of `u.a` occurs here | -------- borrow of `u.a` occurs here
LL | u.a = 1; //[ast]~ ERROR cannot assign to `u.a` because it is borrowed LL | u.a = 1; //~ ERROR cannot assign to `u.a` because it is borrowed
| ^^^^^^^ assignment to borrowed `u.a` occurs here | ^^^^^^^ assignment to borrowed `u.a` occurs here
LL | //[mir]~^ ERROR cannot assign to `u.a` because it is borrowed
LL | drop(rma); LL | drop(rma);
| --- borrow later used here | --- borrow later used here
error[E0502]: cannot borrow `u.b` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `u` (via `u.b`) as immutable because it is also borrowed as mutable (via `u.a`)
--> $DIR/borrowck-union-borrow.rs:88:22 --> $DIR/borrowck-union-borrow.rs:78:22
| |
LL | let rma = &mut u.a; LL | let rma = &mut u.a;
| -------- mutable borrow occurs here | -------- mutable borrow occurs here (via `u.a`)
LL | let rb = &u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `u.a`) LL | let rb = &u.b; //~ ERROR cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `u.a`)
| ^^^^ immutable borrow occurs here | ^^^^ immutable borrow occurs here (via `u.b`)
LL | //[mir]~^ ERROR cannot borrow `u.b` as immutable because it is also borrowed as mutable
LL | drop(rma); LL | drop(rma);
| --- mutable borrow later used here | --- mutable borrow later used here
error[E0503]: cannot use `u.b` because it was mutably borrowed error[E0503]: cannot use `u.b` because it was mutably borrowed
--> $DIR/borrowck-union-borrow.rs:94:21 --> $DIR/borrowck-union-borrow.rs:83:21
| |
LL | let ra = &mut u.a; LL | let ra = &mut u.a;
| -------- borrow of `u.a` occurs here | -------- borrow of `u.a` occurs here
LL | let b = u.b; //[ast]~ ERROR cannot use `u.b` because it was mutably borrowed LL | let b = u.b; //~ ERROR cannot use `u.b` because it was mutably borrowed
| ^^^ use of borrowed `u.a` | ^^^ use of borrowed `u.a`
... LL |
LL | drop(ra); LL | drop(ra);
| -- borrow later used here | -- borrow later used here
error[E0499]: cannot borrow `u.b` as mutable more than once at a time error[E0499]: cannot borrow `u` (via `u.b`) as mutable more than once at a time
--> $DIR/borrowck-union-borrow.rs:101:24 --> $DIR/borrowck-union-borrow.rs:89:24
| |
LL | let rma = &mut u.a; LL | let rma = &mut u.a;
| -------- first mutable borrow occurs here | -------- first mutable borrow occurs here (via `u.a`)
LL | let rmb2 = &mut u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as mutable more than once at a time LL | let rmb2 = &mut u.b; //~ ERROR cannot borrow `u` (via `u.b`) as mutable more than once at a time
| ^^^^^^^^ second mutable borrow occurs here | ^^^^^^^^ second mutable borrow occurs here (via `u.b`)
LL | //[mir]~^ ERROR cannot borrow `u.b` as mutable more than once at a time
LL | drop(rma); LL | drop(rma);
| --- first borrow later used here | --- first borrow later used here
error[E0506]: cannot assign to `u.b` because it is borrowed error[E0506]: cannot assign to `u.b` because it is borrowed
--> $DIR/borrowck-union-borrow.rs:107:13 --> $DIR/borrowck-union-borrow.rs:94:13
| |
LL | let rma = &mut u.a; LL | let rma = &mut u.a;
| -------- borrow of `u.b` occurs here | -------- borrow of `u.b` occurs here
LL | u.b = 1; //[ast]~ ERROR cannot assign to `u.b` because it is borrowed LL | u.b = 1; //~ ERROR cannot assign to `u.b` because it is borrowed
| ^^^^^^^ assignment to borrowed `u.b` occurs here | ^^^^^^^ assignment to borrowed `u.b` occurs here
LL | //[mir]~^ ERROR cannot assign to `u.b` because it is borrowed
LL | drop(rma); LL | drop(rma);
| --- borrow later used here | --- borrow later used here

View file

@ -1,6 +1,4 @@
// ignore-tidy-linelength // ignore-tidy-linelength
// revisions: ast mir
//[mir]compile-flags: -Z borrowck=mir
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
union U { union U {
@ -24,14 +22,12 @@ fn main() {
} }
{ {
let ra = &u.a; let ra = &u.a;
let rma = &mut u.a; //[ast]~ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable let rma = &mut u.a; //~ 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
drop(ra); drop(ra);
} }
{ {
let ra = &u.a; let ra = &u.a;
u.a = 1; //[ast]~ ERROR cannot assign to `u.a` because it is borrowed u.a = 1; //~ ERROR cannot assign to `u.a` because it is borrowed
//[mir]~^ ERROR cannot assign to `u.a` because it is borrowed
drop(ra); drop(ra);
} }
// Imm borrow, other field // Imm borrow, other field
@ -47,65 +43,55 @@ fn main() {
} }
{ {
let ra = &u.a; 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`) let rmb = &mut u.b; //~ ERROR cannot borrow `u` (via `u.b`) as mutable because `u` is also borrowed as immutable (via `u.a`)
//[mir]~^ ERROR cannot borrow `u.b` as mutable because it is also borrowed as immutable
drop(ra); drop(ra);
} }
{ {
let ra = &u.a; let ra = &u.a;
u.b = 1; //[ast]~ ERROR cannot assign to `u.b` because it is borrowed u.b = 1; //~ ERROR cannot assign to `u.b` because it is borrowed
//[mir]~^ ERROR cannot assign to `u.b` because it is borrowed
drop(ra); drop(ra);
} }
// Mut borrow, same field // Mut borrow, same field
{ {
let rma = &mut u.a; let rma = &mut u.a;
let ra = &u.a; //[ast]~ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable let ra = &u.a; //~ 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
drop(rma); drop(rma);
} }
{ {
let ra = &mut u.a; let ra = &mut u.a;
let a = u.a; //[ast]~ ERROR cannot use `u.a` because it was mutably borrowed let a = u.a; //~ ERROR cannot use `u.a` because it was mutably borrowed
//[mir]~^ ERROR cannot use `u.a` because it was mutably borrowed
drop(ra); drop(ra);
} }
{ {
let rma = &mut u.a; let rma = &mut u.a;
let rma2 = &mut u.a; //[ast]~ ERROR cannot borrow `u.a` as mutable more than once at a time let rma2 = &mut u.a; //~ 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
drop(rma); drop(rma);
} }
{ {
let rma = &mut u.a; let rma = &mut u.a;
u.a = 1; //[ast]~ ERROR cannot assign to `u.a` because it is borrowed u.a = 1; //~ ERROR cannot assign to `u.a` because it is borrowed
//[mir]~^ ERROR cannot assign to `u.a` because it is borrowed
drop(rma); drop(rma);
} }
// Mut borrow, other field // Mut borrow, other field
{ {
let rma = &mut u.a; 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`) let rb = &u.b; //~ ERROR cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `u.a`)
//[mir]~^ ERROR cannot borrow `u.b` as immutable because it is also borrowed as mutable
drop(rma); drop(rma);
} }
{ {
let ra = &mut u.a; let ra = &mut u.a;
let b = u.b; //[ast]~ ERROR cannot use `u.b` because it was mutably borrowed let b = u.b; //~ ERROR cannot use `u.b` because it was mutably borrowed
//[mir]~^ ERROR cannot use `u.b` because it was mutably borrowed
drop(ra); drop(ra);
} }
{ {
let rma = &mut u.a; 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 let rmb2 = &mut u.b; //~ ERROR cannot borrow `u` (via `u.b`) as mutable more than once at a time
//[mir]~^ ERROR cannot borrow `u.b` as mutable more than once at a time
drop(rma); drop(rma);
} }
{ {
let rma = &mut u.a; let rma = &mut u.a;
u.b = 1; //[ast]~ ERROR cannot assign to `u.b` because it is borrowed u.b = 1; //~ ERROR cannot assign to `u.b` because it is borrowed
//[mir]~^ ERROR cannot assign to `u.b` because it is borrowed
drop(rma); drop(rma);
} }
} }

View file

@ -1,115 +1,115 @@
error[E0502]: cannot borrow `u.a` as mutable because it is also borrowed as immutable error[E0502]: cannot borrow `u.a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-union-borrow.rs:27:28 --> $DIR/borrowck-union-borrow.rs:25:28
| |
LL | let ra = &u.a; LL | let ra = &u.a;
| --- immutable borrow occurs here | --- immutable borrow occurs here
LL | let rma = &mut u.a; //[ast]~ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable LL | let rma = &mut u.a; //~ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable
| ^^^ mutable borrow occurs here | ^^^ mutable borrow occurs here
... LL | drop(ra);
LL | } LL | }
| - immutable borrow ends here | - immutable borrow ends here
error[E0506]: cannot assign to `u.a` because it is borrowed error[E0506]: cannot assign to `u.a` because it is borrowed
--> $DIR/borrowck-union-borrow.rs:33:13 --> $DIR/borrowck-union-borrow.rs:30:13
| |
LL | let ra = &u.a; LL | let ra = &u.a;
| --- borrow of `u.a` occurs here | --- borrow of `u.a` occurs here
LL | u.a = 1; //[ast]~ ERROR cannot assign to `u.a` because it is borrowed LL | u.a = 1; //~ ERROR cannot assign to `u.a` because it is borrowed
| ^^^^^^^ assignment to borrowed `u.a` occurs here | ^^^^^^^ assignment to borrowed `u.a` occurs here
error[E0502]: cannot borrow `u` (via `u.b`) as mutable because `u` is also borrowed as immutable (via `u.a`) error[E0502]: cannot borrow `u` (via `u.b`) as mutable because `u` is also borrowed as immutable (via `u.a`)
--> $DIR/borrowck-union-borrow.rs:50:28 --> $DIR/borrowck-union-borrow.rs:46:28
| |
LL | let ra = &u.a; LL | let ra = &u.a;
| --- immutable borrow occurs here (via `u.a`) | --- immutable borrow occurs here (via `u.a`)
LL | 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`) LL | let rmb = &mut u.b; //~ ERROR cannot borrow `u` (via `u.b`) as mutable because `u` is also borrowed as immutable (via `u.a`)
| ^^^ mutable borrow occurs here (via `u.b`) | ^^^ mutable borrow occurs here (via `u.b`)
... LL | drop(ra);
LL | } LL | }
| - immutable borrow ends here | - immutable borrow ends here
error[E0506]: cannot assign to `u.b` because it is borrowed error[E0506]: cannot assign to `u.b` because it is borrowed
--> $DIR/borrowck-union-borrow.rs:56:13 --> $DIR/borrowck-union-borrow.rs:51:13
| |
LL | let ra = &u.a; LL | let ra = &u.a;
| --- borrow of `u.b` occurs here | --- borrow of `u.b` occurs here
LL | u.b = 1; //[ast]~ ERROR cannot assign to `u.b` because it is borrowed LL | u.b = 1; //~ ERROR cannot assign to `u.b` because it is borrowed
| ^^^^^^^ assignment to borrowed `u.b` occurs here | ^^^^^^^ assignment to borrowed `u.b` occurs here
error[E0502]: cannot borrow `u.a` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `u.a` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-union-borrow.rs:63:23 --> $DIR/borrowck-union-borrow.rs:57:23
| |
LL | let rma = &mut u.a; LL | let rma = &mut u.a;
| --- mutable borrow occurs here | --- mutable borrow occurs here
LL | let ra = &u.a; //[ast]~ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable LL | let ra = &u.a; //~ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable
| ^^^ immutable borrow occurs here | ^^^ immutable borrow occurs here
... LL | drop(rma);
LL | } LL | }
| - mutable borrow ends here | - mutable borrow ends here
error[E0503]: cannot use `u.a` because it was mutably borrowed error[E0503]: cannot use `u.a` because it was mutably borrowed
--> $DIR/borrowck-union-borrow.rs:69:17 --> $DIR/borrowck-union-borrow.rs:62:17
| |
LL | let ra = &mut u.a; LL | let ra = &mut u.a;
| --- borrow of `u.a` occurs here | --- borrow of `u.a` occurs here
LL | let a = u.a; //[ast]~ ERROR cannot use `u.a` because it was mutably borrowed LL | let a = u.a; //~ ERROR cannot use `u.a` because it was mutably borrowed
| ^ use of borrowed `u.a` | ^ use of borrowed `u.a`
error[E0499]: cannot borrow `u.a` as mutable more than once at a time error[E0499]: cannot borrow `u.a` as mutable more than once at a time
--> $DIR/borrowck-union-borrow.rs:75:29 --> $DIR/borrowck-union-borrow.rs:67:29
| |
LL | let rma = &mut u.a; LL | let rma = &mut u.a;
| --- first mutable borrow occurs here | --- first mutable borrow occurs here
LL | let rma2 = &mut u.a; //[ast]~ ERROR cannot borrow `u.a` as mutable more than once at a time LL | let rma2 = &mut u.a; //~ ERROR cannot borrow `u.a` as mutable more than once at a time
| ^^^ second mutable borrow occurs here | ^^^ second mutable borrow occurs here
... LL | drop(rma);
LL | } LL | }
| - first borrow ends here | - first borrow ends here
error[E0506]: cannot assign to `u.a` because it is borrowed error[E0506]: cannot assign to `u.a` because it is borrowed
--> $DIR/borrowck-union-borrow.rs:81:13 --> $DIR/borrowck-union-borrow.rs:72:13
| |
LL | let rma = &mut u.a; LL | let rma = &mut u.a;
| --- borrow of `u.a` occurs here | --- borrow of `u.a` occurs here
LL | u.a = 1; //[ast]~ ERROR cannot assign to `u.a` because it is borrowed LL | u.a = 1; //~ ERROR cannot assign to `u.a` because it is borrowed
| ^^^^^^^ assignment to borrowed `u.a` occurs here | ^^^^^^^ assignment to borrowed `u.a` occurs here
error[E0502]: cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `u.a`) error[E0502]: cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `u.a`)
--> $DIR/borrowck-union-borrow.rs:88:23 --> $DIR/borrowck-union-borrow.rs:78:23
| |
LL | let rma = &mut u.a; LL | let rma = &mut u.a;
| --- mutable borrow occurs here (via `u.a`) | --- mutable borrow occurs here (via `u.a`)
LL | let rb = &u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `u.a`) LL | let rb = &u.b; //~ ERROR cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `u.a`)
| ^^^ immutable borrow occurs here (via `u.b`) | ^^^ immutable borrow occurs here (via `u.b`)
... LL | drop(rma);
LL | } LL | }
| - mutable borrow ends here | - mutable borrow ends here
error[E0503]: cannot use `u.b` because it was mutably borrowed error[E0503]: cannot use `u.b` because it was mutably borrowed
--> $DIR/borrowck-union-borrow.rs:94:17 --> $DIR/borrowck-union-borrow.rs:83:17
| |
LL | let ra = &mut u.a; LL | let ra = &mut u.a;
| --- borrow of `u.a` occurs here | --- borrow of `u.a` occurs here
LL | let b = u.b; //[ast]~ ERROR cannot use `u.b` because it was mutably borrowed LL | let b = u.b; //~ ERROR cannot use `u.b` because it was mutably borrowed
| ^ use of borrowed `u.a` | ^ use of borrowed `u.a`
error[E0499]: cannot borrow `u` (via `u.b`) as mutable more than once at a time error[E0499]: cannot borrow `u` (via `u.b`) as mutable more than once at a time
--> $DIR/borrowck-union-borrow.rs:101:29 --> $DIR/borrowck-union-borrow.rs:89:29
| |
LL | let rma = &mut u.a; LL | let rma = &mut u.a;
| --- first mutable borrow occurs here (via `u.a`) | --- first mutable borrow occurs here (via `u.a`)
LL | let rmb2 = &mut u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as mutable more than once at a time LL | let rmb2 = &mut u.b; //~ ERROR cannot borrow `u` (via `u.b`) as mutable more than once at a time
| ^^^ second mutable borrow occurs here (via `u.b`) | ^^^ second mutable borrow occurs here (via `u.b`)
... LL | drop(rma);
LL | } LL | }
| - first borrow ends here | - first borrow ends here
error[E0506]: cannot assign to `u.b` because it is borrowed error[E0506]: cannot assign to `u.b` because it is borrowed
--> $DIR/borrowck-union-borrow.rs:107:13 --> $DIR/borrowck-union-borrow.rs:94:13
| |
LL | let rma = &mut u.a; LL | let rma = &mut u.a;
| --- borrow of `u.b` occurs here | --- borrow of `u.b` occurs here
LL | u.b = 1; //[ast]~ ERROR cannot assign to `u.b` because it is borrowed LL | u.b = 1; //~ ERROR cannot assign to `u.b` because it is borrowed
| ^^^^^^^ assignment to borrowed `u.b` occurs here | ^^^^^^^ assignment to borrowed `u.b` occurs here
error: aborting due to 12 previous errors error: aborting due to 12 previous errors

View file

@ -1,6 +1,8 @@
#![allow(unused)] #![allow(unused)]
#![feature(nll)] #![feature(nll)]
// ignore-tidy-linelength
#[derive(Clone, Copy, Default)] #[derive(Clone, Copy, Default)]
struct S { struct S {
a: u8, a: u8,
@ -25,8 +27,7 @@ fn main() {
*mref = 22; *mref = 22;
let nref = &u.z.c; let nref = &u.z.c;
//~^ ERROR cannot borrow `u.z.c` as immutable because it is also borrowed as mutable [E0502] //~^ ERROR cannot borrow `u` (via `u.z.c`) as immutable because it is also borrowed as mutable (via `u.s.a`) [E0502]
println!("{} {}", mref, nref) println!("{} {}", mref, nref)
} }
} }

View file

@ -1,12 +1,12 @@
error[E0502]: cannot borrow `u.z.c` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `u` (via `u.z.c`) as immutable because it is also borrowed as mutable (via `u.s.a`)
--> $DIR/issue-45157.rs:27:20 --> $DIR/issue-45157.rs:29:20
| |
LL | let mref = &mut u.s.a; LL | let mref = &mut u.s.a;
| ---------- mutable borrow occurs here | ---------- mutable borrow occurs here (via `u.s.a`)
... ...
LL | let nref = &u.z.c; LL | let nref = &u.z.c;
| ^^^^^^ immutable borrow occurs here | ^^^^^^ immutable borrow occurs here (via `u.z.c`)
LL | //~^ ERROR cannot borrow `u.z.c` as immutable because it is also borrowed as mutable [E0502] LL | //~^ ERROR cannot borrow `u` (via `u.z.c`) as immutable because it is also borrowed as mutable (via `u.s.a`) [E0502]
LL | println!("{} {}", mref, nref) LL | println!("{} {}", mref, nref)
| ---- mutable borrow later used here | ---- mutable borrow later used here

View file

@ -1,10 +1,10 @@
error[E0502]: cannot borrow `u.y` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `u` (via `u.y`) as immutable because it is also borrowed as mutable (via `u.x.0`)
--> $DIR/union-borrow-move-parent-sibling.rs:15:13 --> $DIR/union-borrow-move-parent-sibling.rs:15:13
| |
LL | let a = &mut u.x.0; LL | let a = &mut u.x.0;
| ---------- mutable borrow occurs here | ---------- mutable borrow occurs here (via `u.x.0`)
LL | let b = &u.y; //~ ERROR cannot borrow `u.y` LL | let b = &u.y; //~ ERROR cannot borrow `u.y`
| ^^^^ immutable borrow occurs here | ^^^^ immutable borrow occurs here (via `u.y`)
LL | use_borrow(a); LL | use_borrow(a);
| - mutable borrow later used here | - mutable borrow later used here
@ -18,13 +18,13 @@ LL | let b = u.y; //~ ERROR use of moved value: `u.y`
| |
= note: move occurs because `u` has type `U`, which does not implement the `Copy` trait = note: move occurs because `u` has type `U`, which does not implement the `Copy` trait
error[E0502]: cannot borrow `u.y` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `u` (via `u.y`) as immutable because it is also borrowed as mutable (via `u.x.0.0`)
--> $DIR/union-borrow-move-parent-sibling.rs:28:13 --> $DIR/union-borrow-move-parent-sibling.rs:28:13
| |
LL | let a = &mut (u.x.0).0; LL | let a = &mut (u.x.0).0;
| -------------- mutable borrow occurs here | -------------- mutable borrow occurs here (via `u.x.0.0`)
LL | let b = &u.y; //~ ERROR cannot borrow `u.y` LL | let b = &u.y; //~ ERROR cannot borrow `u.y`
| ^^^^ immutable borrow occurs here | ^^^^ immutable borrow occurs here (via `u.y`)
LL | use_borrow(a); LL | use_borrow(a);
| - mutable borrow later used here | - mutable borrow later used here
@ -38,13 +38,13 @@ LL | let b = u.y; //~ ERROR use of moved value: `u.y`
| |
= note: move occurs because `u` has type `U`, which does not implement the `Copy` trait = note: move occurs because `u` has type `U`, which does not implement the `Copy` trait
error[E0502]: cannot borrow `u.x` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `u` (via `u.x`) as immutable because it is also borrowed as mutable (via `*u.y`)
--> $DIR/union-borrow-move-parent-sibling.rs:41:13 --> $DIR/union-borrow-move-parent-sibling.rs:41:13
| |
LL | let a = &mut *u.y; LL | let a = &mut *u.y;
| --------- mutable borrow occurs here | --------- mutable borrow occurs here (via `*u.y`)
LL | let b = &u.x; //~ ERROR cannot borrow `u` (via `u.x`) LL | let b = &u.x; //~ ERROR cannot borrow `u` (via `u.x`)
| ^^^^ immutable borrow occurs here | ^^^^ immutable borrow occurs here (via `u.x`)
LL | use_borrow(a); LL | use_borrow(a);
| - mutable borrow later used here | - mutable borrow later used here