Auto merge of #53438 - matthewjasper:permissive-match-access, r=pnkfelix

[NLL] Be more permissive when checking access due to Match

Partially addresses #53114. notably, we should now have parity with AST borrowck. Matching on uninitialized values is still forbidden.

* ~~Give fake borrows for match their own `BorrowKind`~~
* ~~Allow borrows with this kind to happen on values that are already mutably borrowed.~~
* ~~Track borrows with this type even behind shared reference dereferences and consider all accesses to be deep when checking for conflicts with this borrow type. See [src/test/ui/issues/issue-27282-mutate-before-diverging-arm-3.rs](cb5c989598 (diff-a2126cd3263a1f5342e2ecd5e699fbc6)) for an example soundness issue this fixes (a case of #27282 that wasn't handled correctly).~~
* Create a new `BorrowKind`: `Shallow` (name can be bike-shed)
* `Shallow` borrows differ from shared borrows in that
  * When we check for access we treat them as a `Shallow(Some(_))` read
  * When we check for conflicts with them, if the borrow place is a strict prefix of the access place then we don't consider that a conflict.
    * For example, a `Shallow` borrow of `x` does not conflict with any access or borrow of `x.0` or `*x`
* Remove the current fake borrow in matches.
* When building matches, we take a `Shallow` borrow of any `Place` that we switch on or bind in a match, and any prefix of those places. (There are some optimizations where we do fewer borrows, but this shouldn't change semantics)
  * `match x { &Some(1) => (),  _ => (), }` would `Shallow` borrow `x`, `*x` and `(*x as Some).0` (the `*x` borrow is unnecessary, but I'm not sure how easy it would be to remove.)
* Replace the fake discriminant read with a `ReadForMatch`.
* Change ReadForMatch to only check for initializedness (to prevent `let x: !; match x {}`), but not conflicting borrows. It is still considered a use for liveness and `unsafe` checking.
* Give special cased error messages for this kind of borrow.

Table from the above issue after this PR

| Thing | AST | MIR | Want | Example |
| --- | --- | --- | --- |---|
| `let _ = <unsafe-field>` | 💚  | 💚  |  |  [playground](https://play.rust-lang.org/?gist=bb7843e42fa5318c1043d04bd72abfe4&version=nightly&mode=debug&edition=2015) |
| `match <unsafe_field> { _ => () }` |   |  |  | [playground](https://play.rust-lang.org/?gist=3e3af05fbf1fae28fab2aaf9412fb2ea&version=nightly&mode=debug&edition=2015) |
| `let _ = <moved>` | 💚  | 💚 | 💚 | [playground](https://play.rust-lang.org/?gist=91a6efde8288558e584aaeee0a50558b&version=nightly&mode=debug&edition=2015) |
| `match <moved> { _ => () }` |  |   | 💚 | [playground](https://play.rust-lang.org/?gist=804f8185040b2fe131f2c4a64b3048ca&version=nightly&mode=debug&edition=2015) |
| `let _ = <borrowed>` | 💚  | 💚 | 💚 | [playground](https://play.rust-lang.org/?gist=0e487c2893b89cb772ec2f2b7c5da876&version=nightly&mode=debug&edition=2015) |
| `match <borrowed> { _ => () }` | 💚  | 💚 | 💚 | [playground](https://play.rust-lang.org/?gist=0e487c2893b89cb772ec2f2b7c5da876&version=nightly&mode=debug&edition=2015) |

r? @nikomatsakis
This commit is contained in:
bors 2018-09-25 01:04:12 +00:00
commit 3a2190a9cd
53 changed files with 1197 additions and 906 deletions

View file

@ -63,7 +63,6 @@ impl Drop for S {
//
// bb4: {
// StorageDead(_2);
// FakeRead(ForLet, _1);
// StorageLive(_4);
// _4 = move _1;
// _3 = const std::mem::drop(move _4) -> [return: bb5, unwind: bb7];

View file

@ -34,10 +34,9 @@ fn main() {
// }
// let mut _1: ();
// let mut _3: bool;
// let mut _4: u8;
// let mut _5: !;
// let mut _6: ();
// let mut _7: &i32;
// let mut _4: !;
// let mut _5: ();
// let mut _6: &i32;
// bb0: {
// goto -> bb1;
// }
@ -51,7 +50,7 @@ fn main() {
// StorageLive(_2);
// StorageLive(_3);
// _3 = const true;
// _4 = discriminant(_3);
// FakeRead(ForMatchedPlace, _3);
// switchInt(_3) -> [false: bb11, otherwise: bb10];
// }
// bb4: {
@ -89,9 +88,9 @@ fn main() {
// bb14: {
// FakeRead(ForLet, _2);
// StorageDead(_3);
// StorageLive(_7);
// _7 = &_2;
// _6 = const std::mem::drop(move _7) -> [return: bb28, unwind: bb4];
// StorageLive(_6);
// _6 = &_2;
// _5 = const std::mem::drop(move _6) -> [return: bb28, unwind: bb4];
// }
// bb15: {
// goto -> bb16;
@ -129,15 +128,15 @@ fn main() {
// goto -> bb2;
// }
// bb26: {
// _5 = ();
// _4 = ();
// unreachable;
// }
// bb27: {
// StorageDead(_5);
// StorageDead(_4);
// goto -> bb14;
// }
// bb28: {
// StorageDead(_7);
// StorageDead(_6);
// _1 = ();
// StorageDead(_2);
// goto -> bb1;

View file

@ -53,10 +53,11 @@ fn main() {
// bb0: {
// ...
// _2 = std::option::Option<i32>::Some(const 42i32,);
// _3 = discriminant(_2);
// _4 = &(promoted[1]: std::option::Option<i32>);
// _9 = discriminant(_2);
// switchInt(move _9) -> [0isize: bb5, 1isize: bb3, otherwise: bb7];
// FakeRead(ForMatchedPlace, _2);
// _7 = discriminant(_2);
// _9 = &shallow (promoted[2]: std::option::Option<i32>);
// _10 = &(((promoted[1]: std::option::Option<i32>) as Some).0: i32);
// switchInt(move _7) -> [0isize: bb5, 1isize: bb3, otherwise: bb7];
// }
// bb1: {
// resume;
@ -66,15 +67,18 @@ fn main() {
// goto -> bb13;
// }
// bb3: { // binding3(empty) and arm3
// FakeRead(ForMatch, _4);
// FakeRead(ForMatchGuard, _9);
// FakeRead(ForMatchGuard, _10);
// falseEdges -> [real: bb8, imaginary: bb4]; //pre_binding1
// }
// bb4: {
// FakeRead(ForMatch, _4);
// FakeRead(ForMatchGuard, _9);
// FakeRead(ForMatchGuard, _10);
// falseEdges -> [real: bb12, imaginary: bb5]; //pre_binding2
// }
// bb5: {
// FakeRead(ForMatch, _4);
// FakeRead(ForMatchGuard, _9);
// FakeRead(ForMatchGuard, _10);
// falseEdges -> [real: bb2, imaginary: bb6]; //pre_binding3
// }
// bb6: {
@ -84,31 +88,31 @@ fn main() {
// unreachable;
// }
// bb8: { // binding1 and guard
// StorageLive(_7);
// _7 = &(((promoted[0]: std::option::Option<i32>) as Some).0: i32);
// StorageLive(_10);
// _10 = const guard() -> [return: bb9, unwind: bb1];
// StorageLive(_5);
// _5 = &(((promoted[0]: std::option::Option<i32>) as Some).0: i32);
// StorageLive(_8);
// _8 = const guard() -> [return: bb9, unwind: bb1];
// }
// bb9: {
// switchInt(move _10) -> [false: bb10, otherwise: bb11];
// switchInt(move _8) -> [false: bb10, otherwise: bb11];
// }
// bb10: { // to pre_binding2
// falseEdges -> [real: bb4, imaginary: bb4];
// }
// bb11: { // bindingNoLandingPads.before.mir2 and arm2
// StorageLive(_5);
// _5 = ((_2 as Some).0: i32);
// StorageLive(_3);
// _3 = ((_2 as Some).0: i32);
// StorageLive(_11);
// _11 = _5;
// _11 = _3;
// _1 = (const 1i32, move _11);
// StorageDead(_11);
// goto -> bb13;
// }
// bb12: {
// StorageLive(_8);
// _8 = ((_2 as Some).0: i32);
// StorageLive(_6);
// _6 = ((_2 as Some).0: i32);
// StorageLive(_12);
// _12 = _8;
// _12 = _6;
// _1 = (const 2i32, move_12);
// StorageDead(_12);
// goto -> bb13;
@ -123,10 +127,11 @@ fn main() {
// bb0: {
// ...
// _2 = std::option::Option<i32>::Some(const 42i32,);
// _3 = discriminant(_2);
// _4 = &_2;
// _9 = discriminant(_2);
// switchInt(move _9) -> [0isize: bb4, 1isize: bb3, otherwise: bb7];
// FakeRead(ForMatchedPlace, _2);
// _7 = discriminant(_2);
// _9 = &shallow _2;
// _10 = &((_2 as Some).0: i32);
// switchInt(move _7) -> [0isize: bb4, 1isize: bb3, otherwise: bb7];
// }
// bb1: {
// resume;
@ -136,15 +141,18 @@ fn main() {
// goto -> bb13;
// }
// bb3: {
// FakeRead(ForMatch, _4);
// FakeRead(ForMatchGuard, _9);
// FakeRead(ForMatchGuard, _10);
// falseEdges -> [real: bb8, imaginary: bb4]; //pre_binding1
// }
// bb4: {
// FakeRead(ForMatch, _4);
// FakeRead(ForMatchGuard, _9);
// FakeRead(ForMatchGuard, _10);
// falseEdges -> [real: bb2, imaginary: bb5]; //pre_binding2
// }
// bb5: {
// FakeRead(ForMatch, _4);
// FakeRead(ForMatchGuard, _9);
// FakeRead(ForMatchGuard, _10);
// falseEdges -> [real: bb12, imaginary: bb6]; //pre_binding3
// }
// bb6: {
@ -154,31 +162,31 @@ fn main() {
// unreachable;
// }
// bb8: { // binding1 and guard
// StorageLive(_7);
// _7 = &((_2 as Some).0: i32);
// StorageLive(_10);
// _10 = const guard() -> [return: bb9, unwind: bb1];
// StorageLive(_5);
// _5 = &((_2 as Some).0: i32);
// StorageLive(_8);
// _8 = const guard() -> [return: bb9, unwind: bb1];
// }
// bb9: { // end of guard
// switchInt(move _10) -> [false: bb10, otherwise: bb11];
// switchInt(move _8) -> [false: bb10, otherwise: bb11];
// }
// bb10: { // to pre_binding3 (can skip 2 since this is `Some`)
// falseEdges -> [real: bb5, imaginary: bb4];
// }
// bb11: { // arm1
// StorageLive(_5);
// _5 = ((_2 as Some).0: i32);
// StorageLive(_3);
// _3 = ((_2 as Some).0: i32);
// StorageLive(_11);
// _11 = _5;
// _11 = _3;
// _1 = (const 1i32, move _11);
// StorageDead(_11);
// goto -> bb13;
// }
// bb12: { // binding3 and arm3
// StorageLive(_8);
// _8 = ((_2 as Some).0: i32);
// StorageLive(_6);
// _6 = ((_2 as Some).0: i32);
// StorageLive(_12);
// _12 = _8;
// _12 = _6;
// _1 = (const 2i32, move _12);
// StorageDead(_12);
// goto -> bb13;
@ -193,81 +201,86 @@ fn main() {
// bb0: {
// ...
// _2 = std::option::Option<i32>::Some(const 1i32,);
// _3 = discriminant(_2);
// _4 = &_2;
// _13 = discriminant(_2);
// switchInt(move _13) -> [1isize: bb2, otherwise: bb3];
// FakeRead(ForMatchedPlace, _2);
// _11 = discriminant(_2);
// _16 = &shallow _2;
// _17 = &((_2 as Some).0: i32);
// switchInt(move _11) -> [1isize: bb2, otherwise: bb3];
// }
// bb1: {
// resume;
// }
// bb2: {
// FakeRead(ForMatch, _4);
// FakeRead(ForMatchGuard, _16);
// FakeRead(ForMatchGuard, _17);
// falseEdges -> [real: bb7, imaginary: bb3]; //pre_binding1
// }
// bb3: {
// FakeRead(ForMatch, _4);
// FakeRead(ForMatchGuard, _16);
// FakeRead(ForMatchGuard, _17);
// falseEdges -> [real: bb11, imaginary: bb4]; //pre_binding2
// }
// bb4: {
// FakeRead(ForMatch, _4);
// FakeRead(ForMatchGuard, _16);
// FakeRead(ForMatchGuard, _17);
// falseEdges -> [real: bb12, imaginary: bb5]; //pre_binding3
// }
// bb5: {
// FakeRead(ForMatch, _4);
// FakeRead(ForMatchGuard, _16);
// FakeRead(ForMatchGuard, _17);
// falseEdges -> [real: bb16, imaginary: bb6]; //pre_binding4
// }
// bb6: {
// unreachable;
// }
// bb7: { // binding1: Some(w) if guard()
// StorageLive(_7);
// _7 = &((_2 as Some).0: i32);
// StorageLive(_14);
// _14 = const guard() -> [return: bb8, unwind: bb1];
// StorageLive(_5);
// _5 = &((_2 as Some).0: i32);
// StorageLive(_12);
// _12 = const guard() -> [return: bb8, unwind: bb1];
// }
// bb8: { //end of guard
// switchInt(move _14) -> [false: bb9, otherwise: bb10];
// switchInt(move _12) -> [false: bb9, otherwise: bb10];
// }
// bb9: { // to pre_binding2
// falseEdges -> [real: bb3, imaginary: bb3];
// }
// bb10: { // set up bindings for arm1
// StorageLive(_5);
// _5 = ((_2 as Some).0: i32);
// StorageLive(_3);
// _3 = ((_2 as Some).0: i32);
// _1 = const 1i32;
// goto -> bb17;
// }
// bb11: { // binding2 & arm2
// StorageLive(_8);
// _8 = _2;
// StorageLive(_6);
// _6 = _2;
// _1 = const 2i32;
// goto -> bb17;
// }
// bb12: { // binding3: Some(y) if guard2(y)
// StorageLive(_11);
// _11 = &((_2 as Some).0: i32);
// StorageLive(_16);
// StorageLive(_17);
// _17 = (*_11);
// _16 = const guard2(move _17) -> [return: bb13, unwind: bb1];
// StorageLive(_9);
// _9 = &((_2 as Some).0: i32);
// StorageLive(_14);
// StorageLive(_15);
// _15 = (*_9);
// _14 = const guard2(move _15) -> [return: bb13, unwind: bb1];
// }
// bb13: { // end of guard2
// StorageDead(_17);
// switchInt(move _16) -> [false: bb14, otherwise: bb15];
// StorageDead(_15);
// switchInt(move _14) -> [false: bb14, otherwise: bb15];
// }
// bb14: { // to pre_binding4
// falseEdges -> [real: bb5, imaginary: bb5];
// }
// bb15: { // set up bindings for arm3
// StorageLive(_9);
// _9 = ((_2 as Some).0: i32);
// StorageLive(_7);
// _7 = ((_2 as Some).0: i32);
// _1 = const 3i32;
// goto -> bb17;
// }
// bb16: { // binding4 & arm4
// StorageLive(_12);
// _12 = _2;
// StorageLive(_10);
// _10 = _2;
// _1 = const 4i32;
// goto -> bb17;
// }

View file

@ -0,0 +1,122 @@
// Test that the fake borrows for matches are removed after borrow checking.
// ignore-wasm32-bare
#![feature(nll)]
fn match_guard(x: Option<&&i32>) -> i32 {
match x {
Some(0) if true => 0,
_ => 1,
}
}
fn main() {
match_guard(None);
}
// END RUST SOURCE
// START rustc.match_guard.CleanFakeReadsAndBorrows.before.mir
// bb0: {
// FakeRead(ForMatchedPlace, _1);
// _2 = discriminant(_1);
// _3 = &shallow _1;
// _4 = &shallow ((_1 as Some).0: &'<empty> &'<empty> i32);
// _5 = &shallow (*((_1 as Some).0: &'<empty> &'<empty> i32));
// _6 = &shallow (*(*((_1 as Some).0: &'<empty> &'<empty> i32)));
// switchInt(move _2) -> [1isize: bb6, otherwise: bb4];
// }
// bb1: {
// _0 = const 0i32;
// goto -> bb9;
// }
// bb2: {
// _0 = const 1i32;
// goto -> bb9;
// }
// bb3: {
// FakeRead(ForMatchGuard, _3);
// FakeRead(ForMatchGuard, _4);
// FakeRead(ForMatchGuard, _5);
// FakeRead(ForMatchGuard, _6);
// goto -> bb7;
// }
// bb4: {
// FakeRead(ForMatchGuard, _3);
// FakeRead(ForMatchGuard, _4);
// FakeRead(ForMatchGuard, _5);
// FakeRead(ForMatchGuard, _6);
// goto -> bb2;
// }
// bb5: {
// unreachable;
// }
// bb6: {
// switchInt((*(*((_1 as Some).0: &'<empty> &'<empty> i32)))) -> [0i32: bb3, otherwise: bb4];
// }
// bb7: {
// goto -> bb1;
// }
// bb8: {
// goto -> bb4;
// }
// bb9: {
// return;
// }
// bb10: {
// resume;
// }
// END rustc.match_guard.CleanFakeReadsAndBorrows.before.mir
// START rustc.match_guard.CleanFakeReadsAndBorrows.after.mir
// bb0: {
// nop;
// _2 = discriminant(_1);
// nop;
// nop;
// nop;
// nop;
// switchInt(move _2) -> [1isize: bb6, otherwise: bb4];
// }
// bb1: {
// _0 = const 0i32;
// goto -> bb9;
// }
// bb2: {
// _0 = const 1i32;
// goto -> bb9;
// }
// bb3: {
// nop;
// nop;
// nop;
// nop;
// goto -> bb7;
// }
// bb4: {
// nop;
// nop;
// nop;
// nop;
// goto -> bb2;
// }
// bb5: {
// unreachable;
// }
// bb6: {
// switchInt((*(*((_1 as Some).0: &'<empty> &'<empty> i32)))) -> [0i32: bb3, otherwise: bb4];
// }
// bb7: {
// goto -> bb1;
// }
// bb8: {
// goto -> bb4;
// }
// bb9: {
// return;
// }
// bb10: {
// resume;
// }
// END rustc.match_guard.CleanFakeReadsAndBorrows.after.mir

View file

@ -67,7 +67,6 @@ fn main() {
// Validate(Suspend(ReScope(Remainder { block: ItemLocalId(25), first_statement_index: 0 })), [(*_2): i32]);
// _3 = &ReErased (*_2);
// Validate(Acquire, [(*_3): i32/ReScope(Remainder { block: ItemLocalId(25), first_statement_index: 0 }) (imm)]);
// FakeRead(ForLet, _3);
// _0 = (*_3);
// EndRegion(ReScope(Remainder { block: ItemLocalId(25), first_statement_index: 0 }));
// StorageDead(_3);

View file

@ -28,7 +28,6 @@ fn main() {
// Validate(Acquire, [_1: std::boxed::Box<[i32]>]);
// StorageDead(_2);
// StorageDead(_3);
// FakeRead(ForLet, _1);
// _0 = ();
// Validate(Release, [_1: std::boxed::Box<[i32]>]);
// drop(_1) -> [return: bb2, unwind: bb3];

View file

@ -47,12 +47,10 @@ fn main() {
// bb0: {
// StorageLive(_1);
// _1 = Test { x: const 0i32 };
// FakeRead(ForLet, _1);
// StorageLive(_2);
// Validate(Suspend(ReScope(Remainder { block: ItemLocalId(20), first_statement_index: 3 })), [_1: Test]);
// _2 = &ReErased _1;
// Validate(Acquire, [(*_2): Test/ReScope(Remainder { block: ItemLocalId(20), first_statement_index: 3 }) (imm)]);
// FakeRead(ForLet, _2);
// StorageLive(_4);
// StorageLive(_5);
// Validate(Suspend(ReScope(Node(ItemLocalId(18)))), [((*_2).0: i32): i32/ReScope(Remainder { block: ItemLocalId(20), first_statement_index: 3 }) (imm)]);

View file

@ -1,27 +1,3 @@
error[E0502]: cannot borrow `y` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-anon-fields-struct.rs:23:19
|
LL | Y(ref mut a, _) => a
| --------- mutable borrow occurs here
...
LL | let b = match y {
| ^ immutable borrow occurs here
...
LL | *a += 1;
| ------- borrow later used here
error[E0502]: cannot borrow `y` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-anon-fields-struct.rs:38:19
|
LL | Y(ref mut a, _) => a
| --------- mutable borrow occurs here
...
LL | let b = match y {
| ^ immutable borrow occurs here
...
LL | *a += 1;
| ------- borrow later used here
error[E0499]: cannot borrow `y.0` as mutable more than once at a time
--> $DIR/borrowck-anon-fields-struct.rs:39:11
|
@ -34,7 +10,6 @@ LL | Y(ref mut b, _) => b //~ ERROR cannot borrow
LL | *a += 1;
| ------- borrow later used here
error: aborting due to 3 previous errors
error: aborting due to previous error
Some errors occurred: E0499, E0502.
For more information about an error, try `rustc --explain E0499`.
For more information about this error, try `rustc --explain E0499`.

View file

@ -1,27 +1,3 @@
error[E0502]: cannot borrow `y` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-anon-fields-tuple.rs:21:19
|
LL | (ref mut a, _) => a
| --------- mutable borrow occurs here
...
LL | let b = match y {
| ^ immutable borrow occurs here
...
LL | *a += 1;
| ------- borrow later used here
error[E0502]: cannot borrow `y` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-anon-fields-tuple.rs:36:19
|
LL | (ref mut a, _) => a
| --------- mutable borrow occurs here
...
LL | let b = match y {
| ^ immutable borrow occurs here
...
LL | *a += 1;
| ------- borrow later used here
error[E0499]: cannot borrow `y.0` as mutable more than once at a time
--> $DIR/borrowck-anon-fields-tuple.rs:37:10
|
@ -34,7 +10,6 @@ LL | (ref mut b, _) => b //~ ERROR cannot borrow
LL | *a += 1;
| ------- borrow later used here
error: aborting due to 3 previous errors
error: aborting due to previous error
Some errors occurred: E0499, E0502.
For more information about an error, try `rustc --explain E0499`.
For more information about this error, try `rustc --explain E0499`.

View file

@ -1,27 +1,3 @@
error[E0502]: cannot borrow `y` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-anon-fields-variant.rs:26:19
|
LL | Foo::Y(ref mut a, _) => a,
| --------- mutable borrow occurs here
...
LL | let b = match y {
| ^ immutable borrow occurs here
...
LL | *a += 1;
| ------- borrow later used here
error[E0502]: cannot borrow `y` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-anon-fields-variant.rs:43:19
|
LL | Foo::Y(ref mut a, _) => a,
| --------- mutable borrow occurs here
...
LL | let b = match y {
| ^ immutable borrow occurs here
...
LL | *a += 1;
| ------- borrow later used here
error[E0499]: cannot borrow `y.0` as mutable more than once at a time
--> $DIR/borrowck-anon-fields-variant.rs:44:14
|
@ -34,7 +10,6 @@ LL | Foo::Y(ref mut b, _) => b, //~ ERROR cannot borrow
LL | *a += 1;
| ------- borrow later used here
error: aborting due to 3 previous errors
error: aborting due to previous error
Some errors occurred: E0499, E0502.
For more information about an error, try `rustc --explain E0499`.
For more information about this error, try `rustc --explain E0499`.

View file

@ -28,17 +28,6 @@ LL | let _bar2 = &mut foo.bar1; //~ ERROR cannot borrow
LL | *bar1;
| ----- borrow later used here
error[E0502]: cannot borrow `*foo` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-borrow-from-owned-ptr.rs:72:11
|
LL | let bar1 = &mut foo.bar1;
| ------------- mutable borrow occurs here
LL | match *foo {
| ^^^^ immutable borrow occurs here
...
LL | *bar1;
| ----- borrow later used here
error[E0499]: cannot borrow `foo.bar1` as mutable more than once at a time
--> $DIR/borrowck-borrow-from-owned-ptr.rs:73:21
|
@ -121,7 +110,7 @@ LL | let foo = make_foo();
LL | let bar1 = &mut foo.bar1; //~ ERROR cannot borrow
| ^^^^^^^^^^^^^ cannot borrow as mutable
error: aborting due to 12 previous errors
error: aborting due to 11 previous errors
Some errors occurred: E0499, E0502, E0596.
For more information about an error, try `rustc --explain E0499`.

View file

@ -28,17 +28,6 @@ LL | let _bar2 = &mut foo.bar1; //~ ERROR cannot borrow
LL | *bar1;
| ----- borrow later used here
error[E0502]: cannot borrow `foo` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-borrow-from-stack-variable.rs:70:11
|
LL | let bar1 = &mut foo.bar1;
| ------------- mutable borrow occurs here
LL | match foo {
| ^^^ immutable borrow occurs here
...
LL | *bar1;
| ----- borrow later used here
error[E0499]: cannot borrow `foo.bar1` as mutable more than once at a time
--> $DIR/borrowck-borrow-from-stack-variable.rs:71:21
|
@ -121,7 +110,7 @@ LL | let foo = make_foo();
LL | let bar1 = &mut foo.bar1; //~ ERROR cannot borrow
| ^^^^^^^^^^^^^ cannot borrow as mutable
error: aborting due to 12 previous errors
error: aborting due to 11 previous errors
Some errors occurred: E0499, E0502, E0596.
For more information about an error, try `rustc --explain E0499`.

View file

@ -72,23 +72,12 @@ LL | //[mir]~^ ERROR cannot use `h.0` because it was mutably borrow
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `e` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:77:15
|
LL | let x = e.x();
| - borrow of `e` occurs here
LL | match e { //[mir]~ ERROR cannot use `e` because it was mutably borrowed
| ^ use of borrowed `e`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `e.0` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:78:20
|
LL | let x = e.x();
| - borrow of `e` occurs here
LL | match e { //[mir]~ ERROR cannot use `e` because it was mutably borrowed
LL | match e {
LL | Baz::X(value) => value
| ^^^^^ use of borrowed `e`
...
@ -139,23 +128,12 @@ LL | //[mir]~^ ERROR cannot use `h.0` because it was mutably borrow
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `*e` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:120:15
|
LL | let x = e.x();
| - borrow of `*e` occurs here
LL | match *e { //[mir]~ ERROR cannot use `*e` because it was mutably borrowed
| ^^ use of borrowed `*e`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `e.0` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:121:20
|
LL | let x = e.x();
| - borrow of `*e` occurs here
LL | match *e { //[mir]~ ERROR cannot use `*e` because it was mutably borrowed
LL | match *e {
LL | Baz::X(value) => value
| ^^^^^ use of borrowed `*e`
...
@ -173,41 +151,18 @@ LL | //[mir]~^ ERROR cannot use `u.a` because it was mutably borrow
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:139:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:140:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
LL | match v {
LL | &[x, _, .., _, _] => println!("{}", x),
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:145:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
...
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:146:18
|
@ -220,18 +175,6 @@ LL | &[_, x, .., _, _] => println!("{}", x),
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:151:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
...
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:152:25
|
@ -244,18 +187,6 @@ LL | &[_, _, .., x, _] => println!("{}", x),
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:157:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
...
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:158:28
|
@ -268,41 +199,18 @@ LL | &[_, _, .., _, x] => println!("{}", x),
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:169:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:170:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
LL | match v {
LL | &[x..] => println!("{:?}", x),
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:175:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
...
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:176:18
|
@ -315,18 +223,6 @@ LL | &[_, x..] => println!("{:?}", x),
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:181:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
...
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:182:15
|
@ -339,18 +235,6 @@ LL | &[x.., _] => println!("{:?}", x),
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:187:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
...
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:188:18
|
@ -363,23 +247,12 @@ LL | &[_, x.., _] => println!("{:?}", x),
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `e` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:201:15
|
LL | let x = &mut e;
| ------ borrow of `e` occurs here
LL | match e { //[mir]~ ERROR cannot use `e` because it was mutably borrowed
| ^ use of borrowed `e`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `e` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:202:13
|
LL | let x = &mut e;
| ------ borrow of `e` occurs here
LL | match e { //[mir]~ ERROR cannot use `e` because it was mutably borrowed
LL | match e {
LL | E::A(ref ax) =>
| ^^^^^^^^^^^^ use of borrowed `e`
...
@ -391,7 +264,7 @@ error[E0502]: cannot borrow `e.0` as immutable because it is also borrowed as mu
|
LL | let x = &mut e;
| ------ mutable borrow occurs here
LL | match e { //[mir]~ ERROR cannot use `e` because it was mutably borrowed
LL | match e {
LL | E::A(ref ax) =>
| ^^^^^^ immutable borrow occurs here
...
@ -410,41 +283,18 @@ LL | E::B { x: ref bx } =>
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `s` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:220:15
|
LL | let x = &mut s;
| ------ borrow of `s` occurs here
LL | match s { //[mir]~ ERROR cannot use `s` because it was mutably borrowed
| ^ use of borrowed `s`
...
LL | drop(x);
| - borrow later used here
error[E0502]: cannot borrow `s.y.0` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-describe-lvalue.rs:221:22
|
LL | let x = &mut s;
| ------ mutable borrow occurs here
LL | match s { //[mir]~ ERROR cannot use `s` because it was mutably borrowed
LL | match s {
LL | S { y: (ref y0, _), .. } =>
| ^^^^^^ immutable borrow occurs here
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `s` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:227:15
|
LL | let x = &mut s;
| ------ borrow of `s` occurs here
...
LL | match s { //[mir]~ ERROR cannot use `s` because it was mutably borrowed
| ^ use of borrowed `s`
...
LL | drop(x);
| - borrow later used here
error[E0502]: cannot borrow `s.x.y` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-describe-lvalue.rs:228:28
|
@ -479,23 +329,12 @@ LL | v[0].y;
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:282:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0502]: cannot borrow `v[..].x` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-describe-lvalue.rs:283:24
|
LL | let x = &mut v;
| ------ mutable borrow occurs here
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
LL | match v {
LL | &[_, F {x: ref xf, ..}] => println!("{}", xf),
| ^^^^^^ immutable borrow occurs here
...
@ -534,7 +373,7 @@ LL | drop(x); //[ast]~ ERROR use of moved value: `x`
|
= note: move occurs because `x` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
error: aborting due to 46 previous errors
error: aborting due to 32 previous errors
Some errors occurred: E0382, E0499, E0502, E0503.
For more information about an error, try `rustc --explain E0382`.

View file

@ -27,7 +27,7 @@ error[E0503]: cannot use `e.0` because it was mutably borrowed
|
LL | let x = e.x();
| - borrow of `e` occurs here
LL | match e { //[mir]~ ERROR cannot use `e` because it was mutably borrowed
LL | match e {
LL | Baz::X(value) => value
| ^^^^^ use of borrowed `e`
@ -68,7 +68,7 @@ error[E0503]: cannot use `e.0` because it was mutably borrowed
|
LL | let x = e.x();
| - borrow of `*e` occurs here
LL | match *e { //[mir]~ ERROR cannot use `*e` because it was mutably borrowed
LL | match *e {
LL | Baz::X(value) => value
| ^^^^^ use of borrowed `*e`
@ -85,7 +85,7 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed
|
LL | let x = &mut v;
| - borrow of `v` occurs here
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
LL | match v {
LL | &[x, _, .., _, _] => println!("{}", x),
| ^ use of borrowed `v`
@ -121,7 +121,7 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed
|
LL | let x = &mut v;
| - borrow of `v` occurs here
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
LL | match v {
LL | &[x..] => println!("{:?}", x),
| ^ use of borrowed `v`
@ -157,7 +157,7 @@ error[E0502]: cannot borrow `e.0` as immutable because `e` is also borrowed as m
|
LL | let x = &mut e;
| - mutable borrow occurs here
LL | match e { //[mir]~ ERROR cannot use `e` because it was mutably borrowed
LL | match e {
LL | E::A(ref ax) =>
| ^^^^^^ immutable borrow occurs here
...
@ -181,7 +181,7 @@ error[E0502]: cannot borrow `s.y.0` as immutable because `s` is also borrowed as
|
LL | let x = &mut s;
| - mutable borrow occurs here
LL | match s { //[mir]~ ERROR cannot use `s` because it was mutably borrowed
LL | match s {
LL | S { y: (ref y0, _), .. } =>
| ^^^^^^ immutable borrow occurs here
...

View file

@ -72,23 +72,12 @@ LL | //[mir]~^ ERROR cannot use `h.0` because it was mutably borrow
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `e` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:77:15
|
LL | let x = e.x();
| - borrow of `e` occurs here
LL | match e { //[mir]~ ERROR cannot use `e` because it was mutably borrowed
| ^ use of borrowed `e`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `e.0` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:78:20
|
LL | let x = e.x();
| - borrow of `e` occurs here
LL | match e { //[mir]~ ERROR cannot use `e` because it was mutably borrowed
LL | match e {
LL | Baz::X(value) => value
| ^^^^^ use of borrowed `e`
...
@ -139,23 +128,12 @@ LL | //[mir]~^ ERROR cannot use `h.0` because it was mutably borrow
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `*e` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:120:15
|
LL | let x = e.x();
| - borrow of `*e` occurs here
LL | match *e { //[mir]~ ERROR cannot use `*e` because it was mutably borrowed
| ^^ use of borrowed `*e`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `e.0` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:121:20
|
LL | let x = e.x();
| - borrow of `*e` occurs here
LL | match *e { //[mir]~ ERROR cannot use `*e` because it was mutably borrowed
LL | match *e {
LL | Baz::X(value) => value
| ^^^^^ use of borrowed `*e`
...
@ -173,41 +151,18 @@ LL | //[mir]~^ ERROR cannot use `u.a` because it was mutably borrow
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:139:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:140:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
LL | match v {
LL | &[x, _, .., _, _] => println!("{}", x),
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:145:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
...
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:146:18
|
@ -220,18 +175,6 @@ LL | &[_, x, .., _, _] => println!("{}", x),
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:151:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
...
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:152:25
|
@ -244,18 +187,6 @@ LL | &[_, _, .., x, _] => println!("{}", x),
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:157:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
...
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:158:28
|
@ -268,41 +199,18 @@ LL | &[_, _, .., _, x] => println!("{}", x),
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:169:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:170:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
LL | match v {
LL | &[x..] => println!("{:?}", x),
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:175:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
...
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:176:18
|
@ -315,18 +223,6 @@ LL | &[_, x..] => println!("{:?}", x),
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:181:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
...
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:182:15
|
@ -339,18 +235,6 @@ LL | &[x.., _] => println!("{:?}", x),
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:187:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
...
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:188:18
|
@ -363,23 +247,12 @@ LL | &[_, x.., _] => println!("{:?}", x),
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `e` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:201:15
|
LL | let x = &mut e;
| ------ borrow of `e` occurs here
LL | match e { //[mir]~ ERROR cannot use `e` because it was mutably borrowed
| ^ use of borrowed `e`
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `e` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:202:13
|
LL | let x = &mut e;
| ------ borrow of `e` occurs here
LL | match e { //[mir]~ ERROR cannot use `e` because it was mutably borrowed
LL | match e {
LL | E::A(ref ax) =>
| ^^^^^^^^^^^^ use of borrowed `e`
...
@ -391,7 +264,7 @@ error[E0502]: cannot borrow `e.0` as immutable because it is also borrowed as mu
|
LL | let x = &mut e;
| ------ mutable borrow occurs here
LL | match e { //[mir]~ ERROR cannot use `e` because it was mutably borrowed
LL | match e {
LL | E::A(ref ax) =>
| ^^^^^^ immutable borrow occurs here
...
@ -410,41 +283,18 @@ LL | E::B { x: ref bx } =>
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `s` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:220:15
|
LL | let x = &mut s;
| ------ borrow of `s` occurs here
LL | match s { //[mir]~ ERROR cannot use `s` because it was mutably borrowed
| ^ use of borrowed `s`
...
LL | drop(x);
| - borrow later used here
error[E0502]: cannot borrow `s.y.0` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-describe-lvalue.rs:221:22
|
LL | let x = &mut s;
| ------ mutable borrow occurs here
LL | match s { //[mir]~ ERROR cannot use `s` because it was mutably borrowed
LL | match s {
LL | S { y: (ref y0, _), .. } =>
| ^^^^^^ immutable borrow occurs here
...
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `s` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:227:15
|
LL | let x = &mut s;
| ------ borrow of `s` occurs here
...
LL | match s { //[mir]~ ERROR cannot use `s` because it was mutably borrowed
| ^ use of borrowed `s`
...
LL | drop(x);
| - borrow later used here
error[E0502]: cannot borrow `s.x.y` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-describe-lvalue.rs:228:28
|
@ -479,23 +329,12 @@ LL | v[0].y;
LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `v` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:282:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
| ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
error[E0502]: cannot borrow `v[..].x` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-describe-lvalue.rs:283:24
|
LL | let x = &mut v;
| ------ mutable borrow occurs here
LL | match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
LL | match v {
LL | &[_, F {x: ref xf, ..}] => println!("{}", xf),
| ^^^^^^ immutable borrow occurs here
...
@ -534,7 +373,7 @@ LL | drop(x); //[ast]~ ERROR use of moved value: `x`
|
= note: move occurs because `x` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
error: aborting due to 46 previous errors
error: aborting due to 32 previous errors
Some errors occurred: E0382, E0499, E0502, E0503.
For more information about an error, try `rustc --explain E0382`.

View file

@ -74,7 +74,7 @@ fn main() {
{
let mut e = Baz::X(2);
let x = e.x();
match e { //[mir]~ ERROR cannot use `e` because it was mutably borrowed
match e {
Baz::X(value) => value
//[ast]~^ ERROR cannot use `e.0` because it was mutably borrowed
//[mir]~^^ ERROR cannot use `e.0` because it was mutably borrowed
@ -117,7 +117,7 @@ fn main() {
{
let mut e = Box::new(Baz::X(3));
let x = e.x();
match *e { //[mir]~ ERROR cannot use `*e` because it was mutably borrowed
match *e {
Baz::X(value) => value
//[ast]~^ ERROR cannot use `e.0` because it was mutably borrowed
//[mir]~^^ ERROR cannot use `e.0` because it was mutably borrowed
@ -136,25 +136,25 @@ fn main() {
{
let mut v = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let x = &mut v;
match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
match v {
&[x, _, .., _, _] => println!("{}", x),
//[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
//[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed
_ => panic!("other case"),
}
match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
match v {
&[_, x, .., _, _] => println!("{}", x),
//[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
//[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed
_ => panic!("other case"),
}
match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
match v {
&[_, _, .., x, _] => println!("{}", x),
//[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
//[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed
_ => panic!("other case"),
}
match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
match v {
&[_, _, .., _, x] => println!("{}", x),
//[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
//[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed
@ -166,25 +166,25 @@ fn main() {
{
let mut v = &[1, 2, 3, 4, 5];
let x = &mut v;
match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
match v {
&[x..] => println!("{:?}", x),
//[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
//[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed
_ => panic!("other case"),
}
match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
match v {
&[_, x..] => println!("{:?}", x),
//[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
//[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed
_ => panic!("other case"),
}
match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
match v {
&[x.., _] => println!("{:?}", x),
//[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
//[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed
_ => panic!("other case"),
}
match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
match v {
&[_, x.., _] => println!("{:?}", x),
//[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
//[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed
@ -198,7 +198,7 @@ fn main() {
let mut e = E::A(3);
let x = &mut e;
match e { //[mir]~ ERROR cannot use `e` because it was mutably borrowed
match e {
E::A(ref ax) =>
//[ast]~^ ERROR cannot borrow `e.0` as immutable because `e` is also borrowed as mutable
//[mir]~^^ ERROR cannot borrow `e.0` as immutable because it is also borrowed as mutable
@ -217,14 +217,14 @@ fn main() {
struct S { x: F, y: (u32, u32), };
let mut s = S { x: F { x: 1, y: 2}, y: (999, 998) };
let x = &mut s;
match s { //[mir]~ ERROR cannot use `s` because it was mutably borrowed
match s {
S { y: (ref y0, _), .. } =>
//[ast]~^ ERROR cannot borrow `s.y.0` as immutable because `s` is also borrowed as mutable
//[mir]~^^ ERROR cannot borrow `s.y.0` as immutable because it is also borrowed as mutable
println!("y0: {:?}", y0),
_ => panic!("other case"),
}
match s { //[mir]~ ERROR cannot use `s` because it was mutably borrowed
match s {
S { x: F { y: ref x0, .. }, .. } =>
//[ast]~^ ERROR cannot borrow `s.x.y` as immutable because `s` is also borrowed as mutable
//[mir]~^^ ERROR cannot borrow `s.x.y` as immutable because it is also borrowed as mutable
@ -279,7 +279,7 @@ fn main() {
struct F {x: u32, y: u32};
let mut v = &[F{x: 1, y: 2}, F{x: 3, y: 4}];
let x = &mut v;
match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
match v {
&[_, F {x: ref xf, ..}] => println!("{}", xf),
//[mir]~^ ERROR cannot borrow `v[..].x` as immutable because it is also borrowed as mutable
// No errors in AST

View file

@ -1,20 +1,9 @@
error[E0503]: cannot use `foo` because it was mutably borrowed
--> $DIR/borrowck-match-already-borrowed.rs:22:19
|
LL | let p = &mut foo;
| -------- borrow of `foo` occurs here
LL | let _ = match foo { //[mir]~ ERROR [E0503]
| ^^^ use of borrowed `foo`
...
LL | drop(p);
| - borrow later used here
error[E0503]: cannot use `foo` because it was mutably borrowed
--> $DIR/borrowck-match-already-borrowed.rs:23:9
|
LL | let p = &mut foo;
| -------- borrow of `foo` occurs here
LL | let _ = match foo { //[mir]~ ERROR [E0503]
LL | let _ = match foo {
LL | Foo::B => 1, //[mir]~ ERROR [E0503]
| ^^^^^^ use of borrowed `foo`
...
@ -33,23 +22,12 @@ LL | Foo::A(x) => x //[ast]~ ERROR [E0503]
LL | drop(p);
| - borrow later used here
error[E0503]: cannot use `x` because it was mutably borrowed
--> $DIR/borrowck-match-already-borrowed.rs:35:19
|
LL | let r = &mut x;
| ------ borrow of `x` occurs here
LL | let _ = match x { //[mir]~ ERROR [E0503]
| ^ use of borrowed `x`
...
LL | drop(r);
| - borrow later used here
error[E0503]: cannot use `x` because it was mutably borrowed
--> $DIR/borrowck-match-already-borrowed.rs:36:9
|
LL | let r = &mut x;
| ------ borrow of `x` occurs here
LL | let _ = match x { //[mir]~ ERROR [E0503]
LL | let _ = match x {
LL | x => x + 1, //[ast]~ ERROR [E0503]
| ^ use of borrowed `x`
...
@ -68,6 +46,6 @@ LL | y => y + 2, //[ast]~ ERROR [E0503]
LL | drop(r);
| - borrow later used here
error: aborting due to 6 previous errors
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0503`.

View file

@ -12,7 +12,7 @@ error[E0503]: cannot use `x` because it was mutably borrowed
|
LL | let r = &mut x;
| - borrow of `x` occurs here
LL | let _ = match x { //[mir]~ ERROR [E0503]
LL | let _ = match x {
LL | x => x + 1, //[ast]~ ERROR [E0503]
| ^ use of borrowed `x`

View file

@ -1,20 +1,9 @@
error[E0503]: cannot use `foo` because it was mutably borrowed
--> $DIR/borrowck-match-already-borrowed.rs:22:19
|
LL | let p = &mut foo;
| -------- borrow of `foo` occurs here
LL | let _ = match foo { //[mir]~ ERROR [E0503]
| ^^^ use of borrowed `foo`
...
LL | drop(p);
| - borrow later used here
error[E0503]: cannot use `foo` because it was mutably borrowed
--> $DIR/borrowck-match-already-borrowed.rs:23:9
|
LL | let p = &mut foo;
| -------- borrow of `foo` occurs here
LL | let _ = match foo { //[mir]~ ERROR [E0503]
LL | let _ = match foo {
LL | Foo::B => 1, //[mir]~ ERROR [E0503]
| ^^^^^^ use of borrowed `foo`
...
@ -33,23 +22,12 @@ LL | Foo::A(x) => x //[ast]~ ERROR [E0503]
LL | drop(p);
| - borrow later used here
error[E0503]: cannot use `x` because it was mutably borrowed
--> $DIR/borrowck-match-already-borrowed.rs:35:19
|
LL | let r = &mut x;
| ------ borrow of `x` occurs here
LL | let _ = match x { //[mir]~ ERROR [E0503]
| ^ use of borrowed `x`
...
LL | drop(r);
| - borrow later used here
error[E0503]: cannot use `x` because it was mutably borrowed
--> $DIR/borrowck-match-already-borrowed.rs:36:9
|
LL | let r = &mut x;
| ------ borrow of `x` occurs here
LL | let _ = match x { //[mir]~ ERROR [E0503]
LL | let _ = match x {
LL | x => x + 1, //[ast]~ ERROR [E0503]
| ^ use of borrowed `x`
...
@ -68,6 +46,6 @@ LL | y => y + 2, //[ast]~ ERROR [E0503]
LL | drop(r);
| - borrow later used here
error: aborting due to 6 previous errors
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0503`.

View file

@ -19,7 +19,7 @@ enum Foo {
fn match_enum() {
let mut foo = Foo::B;
let p = &mut foo;
let _ = match foo { //[mir]~ ERROR [E0503]
let _ = match foo {
Foo::B => 1, //[mir]~ ERROR [E0503]
_ => 2,
Foo::A(x) => x //[ast]~ ERROR [E0503]
@ -32,7 +32,7 @@ fn match_enum() {
fn main() {
let mut x = 1;
let r = &mut x;
let _ = match x { //[mir]~ ERROR [E0503]
let _ = match x {
x => x + 1, //[ast]~ ERROR [E0503]
//[mir]~^ ERROR [E0503]
y => y + 2, //[ast]~ ERROR [E0503]

View file

@ -1,47 +0,0 @@
warning: this constant cannot be used
--> $DIR/conditional_array_execution.rs:15:1
|
LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
| ^^^^^^^^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| attempt to subtract with overflow
|
note: lint level defined here
--> $DIR/conditional_array_execution.rs:11:9
|
LL | #![warn(const_err)]
| ^^^^^^^^^
error[E0080]: referenced constant has errors
--> $DIR/conditional_array_execution.rs:19:14
|
LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
| ----- attempt to subtract with overflow
...
LL | println!("{}", FOO);
| ^^^^
error[E0080]: erroneous constant used
--> $DIR/conditional_array_execution.rs:19:14
|
LL | println!("{}", FOO);
| ^^^^ --- referenced constant has errors
error[E0080]: referenced constant has errors
--> $DIR/conditional_array_execution.rs:19:20
|
LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
| ----- attempt to subtract with overflow
...
LL | println!("{}", FOO);
| ^^^
error[E0080]: erroneous constant used
--> $DIR/conditional_array_execution.rs:19:20
|
LL | println!("{}", FOO);
| ^^^ referenced constant has errors
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0080`.

View file

@ -1,70 +0,0 @@
warning: this constant cannot be used
--> $DIR/issue-43197.rs:20:5
|
LL | const X: u32 = 0-1;
| ^^^^^^^^^^^^^^^---^
| |
| attempt to subtract with overflow
|
note: lint level defined here
--> $DIR/issue-43197.rs:11:9
|
LL | #![warn(const_err)]
| ^^^^^^^^^
warning: this constant cannot be used
--> $DIR/issue-43197.rs:22:5
|
LL | const Y: u32 = foo(0-1);
| ^^^^^^^^^^^^^^^^^^^---^^
| |
| attempt to subtract with overflow
error[E0080]: referenced constant has errors
--> $DIR/issue-43197.rs:24:14
|
LL | const X: u32 = 0-1;
| --- attempt to subtract with overflow
...
LL | println!("{} {}", X, Y);
| ^^^^^^^
error[E0080]: erroneous constant used
--> $DIR/issue-43197.rs:24:14
|
LL | println!("{} {}", X, Y);
| ^^^^^^^ - referenced constant has errors
error[E0080]: referenced constant has errors
--> $DIR/issue-43197.rs:24:26
|
LL | const Y: u32 = foo(0-1);
| --- attempt to subtract with overflow
LL | //~^ WARN this constant cannot be used
LL | println!("{} {}", X, Y);
| ^
error[E0080]: erroneous constant used
--> $DIR/issue-43197.rs:24:26
|
LL | println!("{} {}", X, Y);
| ^ referenced constant has errors
error[E0080]: referenced constant has errors
--> $DIR/issue-43197.rs:24:23
|
LL | const X: u32 = 0-1;
| --- attempt to subtract with overflow
...
LL | println!("{} {}", X, Y);
| ^
error[E0080]: erroneous constant used
--> $DIR/issue-43197.rs:24:23
|
LL | println!("{} {}", X, Y);
| ^ referenced constant has errors
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0080`.

View file

@ -1,33 +0,0 @@
error[E0080]: referenced constant has errors
--> $DIR/issue-44578.rs:35:14
|
LL | const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize];
| ------------------------------------ index out of bounds: the len is 1 but the index is 1
...
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
| ^^^^
error[E0080]: erroneous constant used
--> $DIR/issue-44578.rs:35:14
|
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
| ^^^^ -------------------------- referenced constant has errors
error[E0080]: referenced constant has errors
--> $DIR/issue-44578.rs:35:20
|
LL | const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize];
| ------------------------------------ index out of bounds: the len is 1 but the index is 1
...
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: erroneous constant used
--> $DIR/issue-44578.rs:35:20
|
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0080`.

View file

@ -24,7 +24,6 @@ fn main() {
match b {
&mut false => {},
_ if { (|| { let bar = b; *bar = false; })();
//~^ ERROR cannot move out of `b` because it is borrowed [E0505]
false } => { },
&mut true => { println!("You might think we should get here"); },
//~^ ERROR use of moved value: `*b` [E0382]

View file

@ -1,29 +1,14 @@
error[E0505]: cannot move out of `b` because it is borrowed
--> $DIR/issue-27282-move-match-input-into-guard.rs:26:17
|
LL | match b {
| - borrow of `b` occurs here
LL | &mut false => {},
LL | _ if { (|| { let bar = b; *bar = false; })();
| ^^ - move occurs due to use in closure
| |
| move out of `b` occurs here
...
LL | &mut true => { println!("You might think we should get here"); },
| --------- borrow later used here
error[E0382]: use of moved value: `*b`
--> $DIR/issue-27282-move-match-input-into-guard.rs:29:14
--> $DIR/issue-27282-move-match-input-into-guard.rs:28:14
|
LL | _ if { (|| { let bar = b; *bar = false; })();
| -- - variable moved due to use in closure
| |
| value moved into closure here
...
LL | false } => { },
LL | &mut true => { println!("You might think we should get here"); },
| ^^^^ value used here after move
error: aborting due to 2 previous errors
error: aborting due to previous error
Some errors occurred: E0382, E0505.
For more information about an error, try `rustc --explain E0382`.
For more information about this error, try `rustc --explain E0382`.

View file

@ -31,7 +31,7 @@ fn main() {
&mut Some(&_) if {
// ForceFnOnce needed to exploit #27282
(|| { *x = None; drop(force_fn_once); })();
//~^ ERROR closure requires unique access to `x` but it is already borrowed [E0500]
//~^ ERROR cannot mutably borrow `x` in match guard [E0510]
false
} => {}
&mut Some(&a) if { // this binds to garbage if we've corrupted discriminant

View file

@ -1,17 +1,14 @@
error[E0500]: closure requires unique access to `x` but it is already borrowed
error[E0510]: cannot mutably borrow `x` in match guard
--> $DIR/issue-27282-mutate-before-diverging-arm-1.rs:33:14
|
LL | match x {
| - borrow occurs here
| - value is immutable in match guard
...
LL | (|| { *x = None; drop(force_fn_once); })();
| ^^ - second borrow occurs due to use of `x` in closure
| ^^ - borrow occurs due to use of `x` in closure
| |
| closure construction occurs here
...
LL | &mut Some(&a) if { // this binds to garbage if we've corrupted discriminant
| ------------- borrow later used here
| cannot mutably borrow
error: aborting due to previous error
For more information about this error, try `rustc --explain E0500`.
For more information about this error, try `rustc --explain E0510`.

View file

@ -36,7 +36,7 @@ fn main() {
if {
// ForceFnOnce needed to exploit #27282
(|| { *x = None; drop(force_fn_once); })();
//~^ ERROR closure requires unique access to `x` but it is already borrowed [E0500]
//~^ ERROR cannot mutably borrow `x` in match guard [E0510]
false
} => {}

View file

@ -1,17 +1,14 @@
error[E0500]: closure requires unique access to `x` but it is already borrowed
error[E0510]: cannot mutably borrow `x` in match guard
--> $DIR/issue-27282-mutate-before-diverging-arm-2.rs:38:18
|
LL | match x {
| - borrow occurs here
| - value is immutable in match guard
...
LL | (|| { *x = None; drop(force_fn_once); })();
| ^^ - second borrow occurs due to use of `x` in closure
| ^^ - borrow occurs due to use of `x` in closure
| |
| closure construction occurs here
...
LL | &mut Some(&2)
| ------------- borrow later used here
| cannot mutably borrow
error: aborting due to previous error
For more information about this error, try `rustc --explain E0500`.
For more information about this error, try `rustc --explain E0510`.

View file

@ -0,0 +1,30 @@
// This is testing an attempt to corrupt the discriminant of the match
// arm in a guard, followed by an attempt to continue matching on that
// corrupted discriminant in the remaining match arms.
//
// Basically this is testing that our new NLL feature of emitting a
// fake read on each match arm is catching cases like this.
//
// This case is interesting because a borrow of **x is untracked, because **x is
// immutable. However, for matches we care that **x refers to the same value
// until we have chosen a match arm.
#![feature(nll)]
struct ForceFnOnce;
fn main() {
let mut x = &mut &Some(&2);
let force_fn_once = ForceFnOnce;
match **x {
None => panic!("unreachable"),
Some(&_) if {
// ForceFnOnce needed to exploit #27282
(|| { *x = &None; drop(force_fn_once); })();
//~^ ERROR cannot mutably borrow `x` in match guard [E0510]
false
} => {}
Some(&a) if { // this binds to garbage if we've corrupted discriminant
println!("{}", a);
panic!()
} => {}
_ => panic!("unreachable"),
}
}

View file

@ -0,0 +1,14 @@
error[E0510]: cannot mutably borrow `x` in match guard
--> $DIR/issue-27282-mutate-before-diverging-arm-3.rs:20:14
|
LL | match **x {
| --- value is immutable in match guard
...
LL | (|| { *x = &None; drop(force_fn_once); })();
| ^^ - borrow occurs due to use of `x` in closure
| |
| cannot mutably borrow
error: aborting due to previous error
For more information about this error, try `rustc --explain E0510`.

View file

@ -21,7 +21,7 @@ fn main() {
let mut e = Xyz::A;
let f = &mut e;
let g = f;
match e { //~ cannot use `e` because it was mutably borrowed [E0503]
match e {
Xyz::A => println!("a"),
//~^ cannot use `e` because it was mutably borrowed [E0503]
Xyz::B => println!("b"),

View file

@ -1,15 +1,3 @@
error[E0503]: cannot use `e` because it was mutably borrowed
--> $DIR/borrowed-match-issue-45045.rs:24:11
|
LL | let f = &mut e;
| ------ borrow of `e` occurs here
LL | let g = f;
LL | match e { //~ cannot use `e` because it was mutably borrowed [E0503]
| ^ use of borrowed `e`
...
LL | *g = Xyz::B;
| ----------- borrow later used here
error[E0503]: cannot use `e` because it was mutably borrowed
--> $DIR/borrowed-match-issue-45045.rs:25:9
|
@ -22,6 +10,6 @@ LL | Xyz::A => println!("a"),
LL | *g = Xyz::B;
| ----------- borrow later used here
error: aborting due to 2 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0503`.

View file

@ -0,0 +1,164 @@
// Test that a (partially) mutably borrowed place can be matched on, so long as
// we don't have to read any values that are mutably borrowed to determine
// which arm to take.
//
// Test that we don't allow mutating the value being matched on in a way that
// changes which patterns it matches, until we have chosen an arm.
// compile-flags: -Zdisable-ast-check-for-mutation-in-guard
#![feature(nll)]
fn ok_mutation_in_guard(mut q: i32) {
match q {
// OK, mutation doesn't change which patterns g matches
_ if { q = 1; false } => (),
_ => (),
}
}
fn ok_indirect_mutation_in_guard(mut p: &bool) {
match *p {
// OK, mutation doesn't change which patterns s matches
_ if {
p = &true;
false
} => (),
_ => (),
}
}
fn mutation_invalidates_pattern_in_guard(mut q: bool) {
match q {
// s doesn't match the pattern with the guard by the end of the guard.
false if {
q = true; //~ ERROR
true
} => (),
_ => (),
}
}
fn mutation_invalidates_previous_pattern_in_guard(mut r: bool) {
match r {
// s matches a previous pattern by the end of the guard.
true => (),
_ if {
r = true; //~ ERROR
true
} => (),
_ => (),
}
}
fn match_on_borrowed_early_end(mut s: bool) {
let h = &mut s;
match s { //~ ERROR
// s changes value between the start of the match and when its value is checked.
_ if {
*h = !*h;
false
} => (),
true => (),
false => (),
}
}
fn bad_mutation_in_guard(mut t: bool) {
match t {
true => (),
false if {
t = true; //~ ERROR
false
} => (),
false => (),
}
}
fn bad_mutation_in_guard2(mut u: bool) {
match u {
// Guard changes the value bound in the last pattern.
_ => (),
_ if {
u = true; //~ ERROR
false
} => (),
x => (),
}
}
pub fn bad_mutation_in_guard3(mut x: Option<Option<&i32>>) {
// Check that nested patterns are checked.
match x {
None => (),
Some(None) => (),
_ if {
match x {
Some(ref mut r) => *r = None, //~ ERROR
_ => return,
};
false
} => (),
Some(Some(r)) => println!("{}", r),
}
}
fn bad_mutation_in_guard4(mut w: (&mut bool,)) {
match w {
// Guard changes the value bound in the last pattern.
_ => (),
_ if {
*w.0 = true; //~ ERROR
false
} => (),
x => (),
}
}
fn bad_indirect_mutation_in_guard(mut y: &bool) {
match *y {
true => (),
false if {
y = &true; //~ ERROR
false
} => (),
false => (),
}
}
fn bad_indirect_mutation_in_guard2(mut z: &bool) {
match z {
&true => (),
&false if {
z = &true; //~ ERROR
false
} => (),
&false => (),
}
}
fn bad_indirect_mutation_in_guard3(mut a: &bool) {
// Same as bad_indirect_mutation_in_guard2, but using match ergonomics
match a {
true => (),
false if {
a = &true; //~ ERROR
false
} => (),
false => (),
}
}
fn bad_indirect_mutation_in_guard4(mut b: &bool) {
match b {
&_ => (),
&_ if {
b = &true; //~ ERROR
false
} => (),
&b => (),
}
}
fn main() {}

View file

@ -0,0 +1,132 @@
error[E0510]: cannot assign `q` in match guard
--> $DIR/match-guards-partially-borrow.rs:35:13
|
LL | match q {
| - value is immutable in match guard
...
LL | q = true; //~ ERROR
| ^^^^^^^^ cannot assign
...
LL | _ => (),
| - borrow later used here
error[E0510]: cannot assign `r` in match guard
--> $DIR/match-guards-partially-borrow.rs:47:13
|
LL | match r {
| - value is immutable in match guard
...
LL | r = true; //~ ERROR
| ^^^^^^^^ cannot assign
...
LL | _ => (),
| - borrow later used here
error[E0503]: cannot use `s` because it was mutably borrowed
--> $DIR/match-guards-partially-borrow.rs:56:11
|
LL | let h = &mut s;
| ------ borrow of `s` occurs here
LL | match s { //~ ERROR
| ^ use of borrowed `s`
...
LL | *h = !*h;
| -- borrow later used here
error[E0510]: cannot assign `t` in match guard
--> $DIR/match-guards-partially-borrow.rs:71:13
|
LL | match t {
| - value is immutable in match guard
...
LL | t = true; //~ ERROR
| ^^^^^^^^ cannot assign
...
LL | false => (),
| ----- borrow later used here
error[E0506]: cannot assign to `u` because it is borrowed
--> $DIR/match-guards-partially-borrow.rs:83:13
|
LL | match u {
| - borrow of `u` occurs here
...
LL | u = true; //~ ERROR
| ^^^^^^^^ assignment to borrowed `u` occurs here
...
LL | x => (),
| - borrow later used here
error[E0510]: cannot mutably borrow `x.0` in match guard
--> $DIR/match-guards-partially-borrow.rs:97:22
|
LL | match x {
| - value is immutable in match guard
...
LL | Some(ref mut r) => *r = None, //~ ERROR
| ^^^^^^^^^ cannot mutably borrow
error[E0506]: cannot assign to `*w.0` because it is borrowed
--> $DIR/match-guards-partially-borrow.rs:112:13
|
LL | match w {
| - borrow of `*w.0` occurs here
...
LL | *w.0 = true; //~ ERROR
| ^^^^^^^^^^^ assignment to borrowed `*w.0` occurs here
...
LL | x => (),
| - borrow later used here
error[E0510]: cannot assign `y` in match guard
--> $DIR/match-guards-partially-borrow.rs:123:13
|
LL | match *y {
| -- value is immutable in match guard
...
LL | y = &true; //~ ERROR
| ^^^^^^^^^ cannot assign
...
LL | false => (),
| ----- borrow later used here
error[E0510]: cannot assign `z` in match guard
--> $DIR/match-guards-partially-borrow.rs:134:13
|
LL | match z {
| - value is immutable in match guard
...
LL | z = &true; //~ ERROR
| ^^^^^^^^^ cannot assign
...
LL | &false => (),
| ------ borrow later used here
error[E0510]: cannot assign `a` in match guard
--> $DIR/match-guards-partially-borrow.rs:146:13
|
LL | match a {
| - value is immutable in match guard
...
LL | a = &true; //~ ERROR
| ^^^^^^^^^ cannot assign
...
LL | false => (),
| ----- borrow later used here
error[E0510]: cannot assign `b` in match guard
--> $DIR/match-guards-partially-borrow.rs:157:13
|
LL | match b {
| - value is immutable in match guard
...
LL | b = &true; //~ ERROR
| ^^^^^^^^^ cannot assign
...
LL | &b => (),
| -- borrow later used here
error: aborting due to 11 previous errors
Some errors occurred: E0503, E0506, E0510.
For more information about an error, try `rustc --explain E0503`.

View file

@ -0,0 +1,95 @@
// Test that a (partially) mutably borrowed place can be matched on, so long as
// we don't have to read any values that are mutably borrowed to determine
// which arm to take.
//
// Test that we don't allow mutating the value being matched on in a way that
// changes which patterns it matches, until we have chosen an arm.
#![feature(nll)]
struct A(i32, i32);
fn struct_example(mut a: A) {
let x = &mut a.0;
match a { // OK, no access of borrowed data
_ if false => (),
A(_, r) => (),
}
x;
}
fn indirect_struct_example(mut b: &mut A) {
let x = &mut b.0;
match *b { // OK, no access of borrowed data
_ if false => (),
A(_, r) => (),
}
x;
}
fn underscore_example(mut c: i32) {
let r = &mut c;
match c { // OK, no access of borrowed data (or any data at all)
_ if false => (),
_ => (),
}
r;
}
enum E {
V(i32, i32),
W,
}
fn enum_example(mut e: E) {
let x = match e {
E::V(ref mut x, _) => x,
E::W => panic!(),
};
match e { // OK, no access of borrowed data
_ if false => (),
E::V(_, r) => (),
E::W => (),
}
x;
}
fn indirect_enum_example(mut f: &mut E) {
let x = match *f {
E::V(ref mut x, _) => x,
E::W => panic!(),
};
match f { // OK, no access of borrowed data
_ if false => (),
E::V(_, r) => (),
E::W => (),
}
x;
}
fn match_on_muatbly_borrowed_ref(mut p: &bool) {
let r = &mut p;
match *p { // OK, no access at all
_ if false => (),
_ => (),
}
r;
}
fn match_on_borrowed(mut t: bool) {
let x = &mut t;
match t {
true => (), //~ ERROR
false => (),
}
x;
}
enum Never {}
fn never_init() {
let n: Never;
match n {} //~ ERROR
}
fn main() {}

View file

@ -0,0 +1,22 @@
error[E0503]: cannot use `t` because it was mutably borrowed
--> $DIR/match-on-borrowed.rs:82:9
|
LL | let x = &mut t;
| ------ borrow of `t` occurs here
LL | match t {
LL | true => (), //~ ERROR
| ^^^^ use of borrowed `t`
...
LL | x;
| - borrow later used here
error[E0381]: use of possibly uninitialized variable: `n`
--> $DIR/match-on-borrowed.rs:92:11
|
LL | match n {} //~ ERROR
| ^ use of possibly uninitialized `n`
error: aborting due to 2 previous errors
Some errors occurred: E0381, E0503.
For more information about an error, try `rustc --explain E0381`.