diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index c662ed6a6bf06..36bc2edcf584e 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -506,25 +506,25 @@ pub enum BorrowKind { /// implicit closure bindings. It is needed when the closure is /// borrowing or mutating a mutable referent, e.g.: /// - /// let x: &mut isize = ...; - /// let y = || *x += 5; + /// let x: &mut isize = ...; + /// let y = || *x += 5; /// /// If we were to try to translate this closure into a more explicit /// form, we'd encounter an error with the code as written: /// - /// struct Env { x: & &mut isize } - /// let x: &mut isize = ...; - /// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn - /// fn fn_ptr(env: &mut Env) { **env.x += 5; } + /// struct Env { x: & &mut isize } + /// let x: &mut isize = ...; + /// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn + /// fn fn_ptr(env: &mut Env) { **env.x += 5; } /// /// This is then illegal because you cannot mutate an `&mut` found /// in an aliasable location. To solve, you'd have to translate with /// an `&mut` borrow: /// - /// struct Env { x: & &mut isize } - /// let x: &mut isize = ...; - /// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x - /// fn fn_ptr(env: &mut Env) { **env.x += 5; } + /// struct Env { x: & &mut isize } + /// let x: &mut isize = ...; + /// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x + /// fn fn_ptr(env: &mut Env) { **env.x += 5; } /// /// Now the assignment to `**env.x` is legal, but creating a /// mutable pointer to `x` is not because `x` is not mutable. We diff --git a/src/test/ui/union/union-borrow-move-parent-sibling.nll.stderr b/src/test/ui/union/union-borrow-move-parent-sibling.nll.stderr index a4f5e41b5291c..6b18aff9f6b83 100644 --- a/src/test/ui/union/union-borrow-move-parent-sibling.nll.stderr +++ b/src/test/ui/union/union-borrow-move-parent-sibling.nll.stderr @@ -1,33 +1,64 @@ +error[E0502]: cannot borrow `u.y` as immutable because it is also borrowed as mutable + --> $DIR/union-borrow-move-parent-sibling.rs:25:13 + | +LL | let a = &mut u.x.0; + | ---------- mutable borrow occurs here +LL | let b = &u.y; //~ ERROR cannot borrow `u.y` + | ^^^^ immutable borrow occurs here +LL | use_borrow(a); + | - mutable borrow later used here + error[E0382]: use of moved value: `u` - --> $DIR/union-borrow-move-parent-sibling.rs:29:13 + --> $DIR/union-borrow-move-parent-sibling.rs:32:13 | LL | let a = u.x.0; | ----- value moved here -LL | let a = u.y; //~ ERROR use of moved value: `u.y` +LL | let b = u.y; //~ ERROR use of moved value: `u.y` | ^^^ value used here after move | = 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 + --> $DIR/union-borrow-move-parent-sibling.rs:38:13 + | +LL | let a = &mut (u.x.0).0; + | -------------- mutable borrow occurs here +LL | let b = &u.y; //~ ERROR cannot borrow `u.y` + | ^^^^ immutable borrow occurs here +LL | use_borrow(a); + | - mutable borrow later used here + error[E0382]: use of moved value: `u` - --> $DIR/union-borrow-move-parent-sibling.rs:41:13 + --> $DIR/union-borrow-move-parent-sibling.rs:45:13 | LL | let a = (u.x.0).0; | --------- value moved here -LL | let a = u.y; //~ ERROR use of moved value: `u.y` +LL | let b = u.y; //~ ERROR use of moved value: `u.y` | ^^^ value used here after move | = 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 + --> $DIR/union-borrow-move-parent-sibling.rs:51:13 + | +LL | let a = &mut *u.y; + | --------- mutable borrow occurs here +LL | let b = &u.x; //~ ERROR cannot borrow `u` (via `u.x`) + | ^^^^ immutable borrow occurs here +LL | use_borrow(a); + | - mutable borrow later used here + error[E0382]: use of moved value: `u` - --> $DIR/union-borrow-move-parent-sibling.rs:53:13 + --> $DIR/union-borrow-move-parent-sibling.rs:58:13 | LL | let a = *u.y; | ---- value moved here -LL | let a = u.x; //~ ERROR use of moved value: `u.x` +LL | let b = u.x; //~ ERROR use of moved value: `u.x` | ^^^ value used here after move | = note: move occurs because `u` has type `U`, which does not implement the `Copy` trait -error: aborting due to 3 previous errors +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0382`. +Some errors occurred: E0382, E0502. +For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/union/union-borrow-move-parent-sibling.rs b/src/test/ui/union/union-borrow-move-parent-sibling.rs index 5f504feabb266..99a073b838ca9 100644 --- a/src/test/ui/union/union-borrow-move-parent-sibling.rs +++ b/src/test/ui/union/union-borrow-move-parent-sibling.rs @@ -17,40 +17,45 @@ union U { y: Box>, } +fn use_borrow(_: &T) {} + unsafe fn parent_sibling_borrow() { let mut u = U { x: ((Vec::new(), Vec::new()), Vec::new()) }; let a = &mut u.x.0; - let a = &u.y; //~ ERROR cannot borrow `u.y` + let b = &u.y; //~ ERROR cannot borrow `u.y` + use_borrow(a); } unsafe fn parent_sibling_move() { let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) }; let a = u.x.0; - let a = u.y; //~ ERROR use of moved value: `u.y` + let b = u.y; //~ ERROR use of moved value: `u.y` } unsafe fn grandparent_sibling_borrow() { let mut u = U { x: ((Vec::new(), Vec::new()), Vec::new()) }; let a = &mut (u.x.0).0; - let a = &u.y; //~ ERROR cannot borrow `u.y` + let b = &u.y; //~ ERROR cannot borrow `u.y` + use_borrow(a); } unsafe fn grandparent_sibling_move() { let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) }; let a = (u.x.0).0; - let a = u.y; //~ ERROR use of moved value: `u.y` + let b = u.y; //~ ERROR use of moved value: `u.y` } unsafe fn deref_sibling_borrow() { let mut u = U { y: Box::default() }; let a = &mut *u.y; - let a = &u.x; //~ ERROR cannot borrow `u` (via `u.x`) + let b = &u.x; //~ ERROR cannot borrow `u` (via `u.x`) + use_borrow(a); } unsafe fn deref_sibling_move() { let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) }; let a = *u.y; - let a = u.x; //~ ERROR use of moved value: `u.x` + let b = u.x; //~ ERROR use of moved value: `u.x` } diff --git a/src/test/ui/union/union-borrow-move-parent-sibling.stderr b/src/test/ui/union/union-borrow-move-parent-sibling.stderr index d855435416e5d..daf5a4f4fccaa 100644 --- a/src/test/ui/union/union-borrow-move-parent-sibling.stderr +++ b/src/test/ui/union/union-borrow-move-parent-sibling.stderr @@ -1,59 +1,62 @@ error[E0502]: cannot borrow `u.y` as immutable because `u.x.0` is also borrowed as mutable - --> $DIR/union-borrow-move-parent-sibling.rs:23:14 + --> $DIR/union-borrow-move-parent-sibling.rs:25:14 | LL | let a = &mut u.x.0; | ----- mutable borrow occurs here -LL | let a = &u.y; //~ ERROR cannot borrow `u.y` +LL | let b = &u.y; //~ ERROR cannot borrow `u.y` | ^^^ immutable borrow occurs here +LL | use_borrow(a); LL | } | - mutable borrow ends here error[E0382]: use of moved value: `u.y` - --> $DIR/union-borrow-move-parent-sibling.rs:29:9 + --> $DIR/union-borrow-move-parent-sibling.rs:32:9 | LL | let a = u.x.0; | - value moved here -LL | let a = u.y; //~ ERROR use of moved value: `u.y` +LL | let b = u.y; //~ ERROR use of moved value: `u.y` | ^ value used here after move | = note: move occurs because `u.y` has type `[type error]`, which does not implement the `Copy` trait error[E0502]: cannot borrow `u.y` as immutable because `u.x.0.0` is also borrowed as mutable - --> $DIR/union-borrow-move-parent-sibling.rs:35:14 + --> $DIR/union-borrow-move-parent-sibling.rs:38:14 | LL | let a = &mut (u.x.0).0; | --------- mutable borrow occurs here -LL | let a = &u.y; //~ ERROR cannot borrow `u.y` +LL | let b = &u.y; //~ ERROR cannot borrow `u.y` | ^^^ immutable borrow occurs here +LL | use_borrow(a); LL | } | - mutable borrow ends here error[E0382]: use of moved value: `u.y` - --> $DIR/union-borrow-move-parent-sibling.rs:41:9 + --> $DIR/union-borrow-move-parent-sibling.rs:45:9 | LL | let a = (u.x.0).0; | - value moved here -LL | let a = u.y; //~ ERROR use of moved value: `u.y` +LL | let b = u.y; //~ ERROR use of moved value: `u.y` | ^ value used here after move | = note: move occurs because `u.y` has type `[type error]`, which does not implement the `Copy` trait error[E0502]: cannot borrow `u` (via `u.x`) as immutable because `u` is also borrowed as mutable (via `*u.y`) - --> $DIR/union-borrow-move-parent-sibling.rs:47:14 + --> $DIR/union-borrow-move-parent-sibling.rs:51:14 | LL | let a = &mut *u.y; | ---- mutable borrow occurs here (via `*u.y`) -LL | let a = &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 (via `u.x`) +LL | use_borrow(a); LL | } | - mutable borrow ends here error[E0382]: use of moved value: `u.x` - --> $DIR/union-borrow-move-parent-sibling.rs:53:9 + --> $DIR/union-borrow-move-parent-sibling.rs:58:9 | LL | let a = *u.y; | - value moved here -LL | let a = u.x; //~ ERROR use of moved value: `u.x` +LL | let b = u.x; //~ ERROR use of moved value: `u.x` | ^ value used here after move | = note: move occurs because `u.x` has type `[type error]`, which does not implement the `Copy` trait