Skip to content

Commit 1ea1a42

Browse files
committed
Rollup merge of rust-lang#55696 - davidtwco:issue-55675, r=pnkfelix
NLL Diagnostic Review 3: Missing errors for borrows of union fields Fixes rust-lang#55675. This PR modifies a test to make it more robust (it also fixes indentation on a doc comment, but that's not the point of the PR). See the linked issue for details. r? @pnkfelix
2 parents 54bc9c2 + ba09ed5 commit 1ea1a42

File tree

4 files changed

+75
-36
lines changed

4 files changed

+75
-36
lines changed

src/librustc/mir/mod.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -506,25 +506,25 @@ pub enum BorrowKind {
506506
/// implicit closure bindings. It is needed when the closure is
507507
/// borrowing or mutating a mutable referent, e.g.:
508508
///
509-
/// let x: &mut isize = ...;
510-
/// let y = || *x += 5;
509+
/// let x: &mut isize = ...;
510+
/// let y = || *x += 5;
511511
///
512512
/// If we were to try to translate this closure into a more explicit
513513
/// form, we'd encounter an error with the code as written:
514514
///
515-
/// struct Env { x: & &mut isize }
516-
/// let x: &mut isize = ...;
517-
/// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn
518-
/// fn fn_ptr(env: &mut Env) { **env.x += 5; }
515+
/// struct Env { x: & &mut isize }
516+
/// let x: &mut isize = ...;
517+
/// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn
518+
/// fn fn_ptr(env: &mut Env) { **env.x += 5; }
519519
///
520520
/// This is then illegal because you cannot mutate an `&mut` found
521521
/// in an aliasable location. To solve, you'd have to translate with
522522
/// an `&mut` borrow:
523523
///
524-
/// struct Env { x: & &mut isize }
525-
/// let x: &mut isize = ...;
526-
/// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
527-
/// fn fn_ptr(env: &mut Env) { **env.x += 5; }
524+
/// struct Env { x: & &mut isize }
525+
/// let x: &mut isize = ...;
526+
/// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
527+
/// fn fn_ptr(env: &mut Env) { **env.x += 5; }
528528
///
529529
/// Now the assignment to `**env.x` is legal, but creating a
530530
/// mutable pointer to `x` is not because `x` is not mutable. We
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,64 @@
1+
error[E0502]: cannot borrow `u.y` as immutable because it is also borrowed as mutable
2+
--> $DIR/union-borrow-move-parent-sibling.rs:25:13
3+
|
4+
LL | let a = &mut u.x.0;
5+
| ---------- mutable borrow occurs here
6+
LL | let b = &u.y; //~ ERROR cannot borrow `u.y`
7+
| ^^^^ immutable borrow occurs here
8+
LL | use_borrow(a);
9+
| - mutable borrow later used here
10+
111
error[E0382]: use of moved value: `u`
2-
--> $DIR/union-borrow-move-parent-sibling.rs:29:13
12+
--> $DIR/union-borrow-move-parent-sibling.rs:32:13
313
|
414
LL | let a = u.x.0;
515
| ----- value moved here
6-
LL | let a = u.y; //~ ERROR use of moved value: `u.y`
16+
LL | let b = u.y; //~ ERROR use of moved value: `u.y`
717
| ^^^ value used here after move
818
|
919
= note: move occurs because `u` has type `U`, which does not implement the `Copy` trait
1020

21+
error[E0502]: cannot borrow `u.y` as immutable because it is also borrowed as mutable
22+
--> $DIR/union-borrow-move-parent-sibling.rs:38:13
23+
|
24+
LL | let a = &mut (u.x.0).0;
25+
| -------------- mutable borrow occurs here
26+
LL | let b = &u.y; //~ ERROR cannot borrow `u.y`
27+
| ^^^^ immutable borrow occurs here
28+
LL | use_borrow(a);
29+
| - mutable borrow later used here
30+
1131
error[E0382]: use of moved value: `u`
12-
--> $DIR/union-borrow-move-parent-sibling.rs:41:13
32+
--> $DIR/union-borrow-move-parent-sibling.rs:45:13
1333
|
1434
LL | let a = (u.x.0).0;
1535
| --------- value moved here
16-
LL | let a = u.y; //~ ERROR use of moved value: `u.y`
36+
LL | let b = u.y; //~ ERROR use of moved value: `u.y`
1737
| ^^^ value used here after move
1838
|
1939
= note: move occurs because `u` has type `U`, which does not implement the `Copy` trait
2040

41+
error[E0502]: cannot borrow `u.x` as immutable because it is also borrowed as mutable
42+
--> $DIR/union-borrow-move-parent-sibling.rs:51:13
43+
|
44+
LL | let a = &mut *u.y;
45+
| --------- mutable borrow occurs here
46+
LL | let b = &u.x; //~ ERROR cannot borrow `u` (via `u.x`)
47+
| ^^^^ immutable borrow occurs here
48+
LL | use_borrow(a);
49+
| - mutable borrow later used here
50+
2151
error[E0382]: use of moved value: `u`
22-
--> $DIR/union-borrow-move-parent-sibling.rs:53:13
52+
--> $DIR/union-borrow-move-parent-sibling.rs:58:13
2353
|
2454
LL | let a = *u.y;
2555
| ---- value moved here
26-
LL | let a = u.x; //~ ERROR use of moved value: `u.x`
56+
LL | let b = u.x; //~ ERROR use of moved value: `u.x`
2757
| ^^^ value used here after move
2858
|
2959
= note: move occurs because `u` has type `U`, which does not implement the `Copy` trait
3060

31-
error: aborting due to 3 previous errors
61+
error: aborting due to 6 previous errors
3262

33-
For more information about this error, try `rustc --explain E0382`.
63+
Some errors occurred: E0382, E0502.
64+
For more information about an error, try `rustc --explain E0382`.

src/test/ui/union/union-borrow-move-parent-sibling.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -17,40 +17,45 @@ union U {
1717
y: Box<Vec<u8>>,
1818
}
1919

20+
fn use_borrow<T>(_: &T) {}
21+
2022
unsafe fn parent_sibling_borrow() {
2123
let mut u = U { x: ((Vec::new(), Vec::new()), Vec::new()) };
2224
let a = &mut u.x.0;
23-
let a = &u.y; //~ ERROR cannot borrow `u.y`
25+
let b = &u.y; //~ ERROR cannot borrow `u.y`
26+
use_borrow(a);
2427
}
2528

2629
unsafe fn parent_sibling_move() {
2730
let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) };
2831
let a = u.x.0;
29-
let a = u.y; //~ ERROR use of moved value: `u.y`
32+
let b = u.y; //~ ERROR use of moved value: `u.y`
3033
}
3134

3235
unsafe fn grandparent_sibling_borrow() {
3336
let mut u = U { x: ((Vec::new(), Vec::new()), Vec::new()) };
3437
let a = &mut (u.x.0).0;
35-
let a = &u.y; //~ ERROR cannot borrow `u.y`
38+
let b = &u.y; //~ ERROR cannot borrow `u.y`
39+
use_borrow(a);
3640
}
3741

3842
unsafe fn grandparent_sibling_move() {
3943
let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) };
4044
let a = (u.x.0).0;
41-
let a = u.y; //~ ERROR use of moved value: `u.y`
45+
let b = u.y; //~ ERROR use of moved value: `u.y`
4246
}
4347

4448
unsafe fn deref_sibling_borrow() {
4549
let mut u = U { y: Box::default() };
4650
let a = &mut *u.y;
47-
let a = &u.x; //~ ERROR cannot borrow `u` (via `u.x`)
51+
let b = &u.x; //~ ERROR cannot borrow `u` (via `u.x`)
52+
use_borrow(a);
4853
}
4954

5055
unsafe fn deref_sibling_move() {
5156
let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) };
5257
let a = *u.y;
53-
let a = u.x; //~ ERROR use of moved value: `u.x`
58+
let b = u.x; //~ ERROR use of moved value: `u.x`
5459
}
5560

5661

src/test/ui/union/union-borrow-move-parent-sibling.stderr

+15-12
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,62 @@
11
error[E0502]: cannot borrow `u.y` as immutable because `u.x.0` is also borrowed as mutable
2-
--> $DIR/union-borrow-move-parent-sibling.rs:23:14
2+
--> $DIR/union-borrow-move-parent-sibling.rs:25:14
33
|
44
LL | let a = &mut u.x.0;
55
| ----- mutable borrow occurs here
6-
LL | let a = &u.y; //~ ERROR cannot borrow `u.y`
6+
LL | let b = &u.y; //~ ERROR cannot borrow `u.y`
77
| ^^^ immutable borrow occurs here
8+
LL | use_borrow(a);
89
LL | }
910
| - mutable borrow ends here
1011

1112
error[E0382]: use of moved value: `u.y`
12-
--> $DIR/union-borrow-move-parent-sibling.rs:29:9
13+
--> $DIR/union-borrow-move-parent-sibling.rs:32:9
1314
|
1415
LL | let a = u.x.0;
1516
| - value moved here
16-
LL | let a = u.y; //~ ERROR use of moved value: `u.y`
17+
LL | let b = u.y; //~ ERROR use of moved value: `u.y`
1718
| ^ value used here after move
1819
|
1920
= note: move occurs because `u.y` has type `[type error]`, which does not implement the `Copy` trait
2021

2122
error[E0502]: cannot borrow `u.y` as immutable because `u.x.0.0` is also borrowed as mutable
22-
--> $DIR/union-borrow-move-parent-sibling.rs:35:14
23+
--> $DIR/union-borrow-move-parent-sibling.rs:38:14
2324
|
2425
LL | let a = &mut (u.x.0).0;
2526
| --------- mutable borrow occurs here
26-
LL | let a = &u.y; //~ ERROR cannot borrow `u.y`
27+
LL | let b = &u.y; //~ ERROR cannot borrow `u.y`
2728
| ^^^ immutable borrow occurs here
29+
LL | use_borrow(a);
2830
LL | }
2931
| - mutable borrow ends here
3032

3133
error[E0382]: use of moved value: `u.y`
32-
--> $DIR/union-borrow-move-parent-sibling.rs:41:9
34+
--> $DIR/union-borrow-move-parent-sibling.rs:45:9
3335
|
3436
LL | let a = (u.x.0).0;
3537
| - value moved here
36-
LL | let a = u.y; //~ ERROR use of moved value: `u.y`
38+
LL | let b = u.y; //~ ERROR use of moved value: `u.y`
3739
| ^ value used here after move
3840
|
3941
= note: move occurs because `u.y` has type `[type error]`, which does not implement the `Copy` trait
4042

4143
error[E0502]: cannot borrow `u` (via `u.x`) as immutable because `u` is also borrowed as mutable (via `*u.y`)
42-
--> $DIR/union-borrow-move-parent-sibling.rs:47:14
44+
--> $DIR/union-borrow-move-parent-sibling.rs:51:14
4345
|
4446
LL | let a = &mut *u.y;
4547
| ---- mutable borrow occurs here (via `*u.y`)
46-
LL | let a = &u.x; //~ ERROR cannot borrow `u` (via `u.x`)
48+
LL | let b = &u.x; //~ ERROR cannot borrow `u` (via `u.x`)
4749
| ^^^ immutable borrow occurs here (via `u.x`)
50+
LL | use_borrow(a);
4851
LL | }
4952
| - mutable borrow ends here
5053

5154
error[E0382]: use of moved value: `u.x`
52-
--> $DIR/union-borrow-move-parent-sibling.rs:53:9
55+
--> $DIR/union-borrow-move-parent-sibling.rs:58:9
5356
|
5457
LL | let a = *u.y;
5558
| - value moved here
56-
LL | let a = u.x; //~ ERROR use of moved value: `u.x`
59+
LL | let b = u.x; //~ ERROR use of moved value: `u.x`
5760
| ^ value used here after move
5861
|
5962
= note: move occurs because `u.x` has type `[type error]`, which does not implement the `Copy` trait

0 commit comments

Comments
 (0)