Make conflicting borrow description more robust.

This commit improves the logic for place descriptions in conflicting
borrow errors so that borrows of union fields have better messages even
when the unions are embedded in other unions or structs.
This commit is contained in:
David Wood 2019-01-04 20:56:41 +01:00
parent 69bded2493
commit 388dffe347
No known key found for this signature in database
GPG key ID: 01760B4F9F53F154
3 changed files with 187 additions and 31 deletions

View file

@ -0,0 +1,69 @@
#![allow(unused)]
#![feature(nll)]
// ignore-tidy-linelength
// This tests the error messages for borrows of union fields when the unions are embedded in other
// structs or unions.
#[derive(Clone, Copy, Default)]
struct Leaf {
l1_u8: u8,
l2_u8: u8,
}
#[derive(Clone, Copy)]
union First {
f1_leaf: Leaf,
f2_leaf: Leaf,
f3_union: Second,
}
#[derive(Clone, Copy)]
union Second {
s1_leaf: Leaf,
s2_leaf: Leaf,
}
struct Root {
r1_u8: u8,
r2_union: First,
}
// Borrow a different field of the nested union.
fn nested_union() {
unsafe {
let mut r = Root {
r1_u8: 3,
r2_union: First { f3_union: Second { s2_leaf: Leaf { l1_u8: 8, l2_u8: 4 } } }
};
let mref = &mut r.r2_union.f3_union.s1_leaf.l1_u8;
// ^^^^^^^
*mref = 22;
let nref = &r.r2_union.f3_union.s2_leaf.l1_u8;
// ^^^^^^^
//~^^ ERROR cannot borrow `r.r2_union.f3_union` (via `r.r2_union.f3_union.s2_leaf.l1_u8`) as immutable because it is also borrowed as mutable (via `r.r2_union.f3_union.s1_leaf.l1_u8`) [E0502]
println!("{} {}", mref, nref)
}
}
// Borrow a different field of the first union.
fn first_union() {
unsafe {
let mut r = Root {
r1_u8: 3,
r2_union: First { f3_union: Second { s2_leaf: Leaf { l1_u8: 8, l2_u8: 4 } } }
};
let mref = &mut r.r2_union.f2_leaf.l1_u8;
// ^^^^^^^
*mref = 22;
let nref = &r.r2_union.f1_leaf.l1_u8;
// ^^^^^^^
//~^^ ERROR cannot borrow `r.r2_union` (via `r.r2_union.f1_leaf.l1_u8`) as immutable because it is also borrowed as mutable (via `r.r2_union.f2_leaf.l1_u8`) [E0502]
println!("{} {}", mref, nref)
}
}
fn main() {}

View file

@ -0,0 +1,27 @@
error[E0502]: cannot borrow `r.r2_union.f3_union` (via `r.r2_union.f3_union.s2_leaf.l1_u8`) as immutable because it is also borrowed as mutable (via `r.r2_union.f3_union.s1_leaf.l1_u8`)
--> $DIR/issue-57100.rs:44:20
|
LL | let mref = &mut r.r2_union.f3_union.s1_leaf.l1_u8;
| -------------------------------------- mutable borrow occurs here (via `r.r2_union.f3_union.s1_leaf.l1_u8`)
...
LL | let nref = &r.r2_union.f3_union.s2_leaf.l1_u8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ immutable borrow occurs here (via `r.r2_union.f3_union.s2_leaf.l1_u8`)
...
LL | println!("{} {}", mref, nref)
| ---- mutable borrow later used here
error[E0502]: cannot borrow `r.r2_union` (via `r.r2_union.f1_leaf.l1_u8`) as immutable because it is also borrowed as mutable (via `r.r2_union.f2_leaf.l1_u8`)
--> $DIR/issue-57100.rs:62:20
|
LL | let mref = &mut r.r2_union.f2_leaf.l1_u8;
| ----------------------------- mutable borrow occurs here (via `r.r2_union.f2_leaf.l1_u8`)
...
LL | let nref = &r.r2_union.f1_leaf.l1_u8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ immutable borrow occurs here (via `r.r2_union.f1_leaf.l1_u8`)
...
LL | println!("{} {}", mref, nref)
| ---- mutable borrow later used here
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0502`.