1
Fork 0

Rollup merge of #120214 - Nadrieril:fix-120210, r=pnkfelix

match lowering: consistently lower bindings deepest-first

Currently when lowering match expressions to MIR, we do a funny little dance with the order of bindings. I attempt to explain it in the third commit: we handle refutable (i.e. needing a test) patterns differently than irrefutable ones. This leads to inconsistencies, as reported in https://github.com/rust-lang/rust/issues/120210. The reason we need a dance at all is for situations like:

```rust
fn foo1(x: NonCopyStruct) {
    let y @ NonCopyStruct { copy_field: z } = x;
    // the above should turn into
    let z = x.copy_field;
    let y = x;
}
```

Here the `y ```````@```````` binding will move out of `x`, so we need to copy the field first.

I believe that the inconsistency came about when we fixed https://github.com/rust-lang/rust/issues/69971, and didn't notice that the fix didn't extend to refutable patterns. My guess then is that ordering bindings by "deepest-first, otherwise source order" is a sound choice. This PR implements that (at least I hope, match lowering is hard to follow 🥲).

Fixes https://github.com/rust-lang/rust/issues/120210

r? ```````@oli-obk``````` since you merged the original fix to https://github.com/rust-lang/rust/issues/69971
cc ```````@matthewjasper```````
This commit is contained in:
Matthias Krüger 2024-02-08 09:06:33 +01:00 committed by GitHub
commit 7fb36f2d3b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 317 additions and 263 deletions

View file

@ -40,55 +40,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&mut self, &mut self,
candidate: &mut Candidate<'pat, 'tcx>, candidate: &mut Candidate<'pat, 'tcx>,
) -> bool { ) -> bool {
// repeatedly simplify match pairs until fixed point is reached
debug!("{candidate:#?}"); debug!("{candidate:#?}");
// In order to please the borrow checker, in a pattern like `x @ pat` we must lower the
// existing_bindings and new_bindings exists to keep the semantics in order. // bindings in `pat` before `x`. E.g. (#69971):
// Reversing the binding order for bindings after `@` changes the binding order in places
// it shouldn't be changed, for example `let (Some(a), Some(b)) = (x, y)`
// //
// To avoid this, the binding occurs in the following manner:
// * the bindings for one iteration of the following loop occurs in order (i.e. left to
// right)
// * the bindings from the previous iteration of the loop is prepended to the bindings from
// the current iteration (in the implementation this is done by mem::swap and extend)
// * after all iterations, these new bindings are then appended to the bindings that were
// preexisting (i.e. `candidate.binding` when the function was called).
//
// example:
// candidate.bindings = [1, 2, 3]
// binding in iter 1: [4, 5]
// binding in iter 2: [6, 7]
//
// final binding: [1, 2, 3, 6, 7, 4, 5]
let mut existing_bindings = mem::take(&mut candidate.bindings);
let mut new_bindings = Vec::new();
loop {
let match_pairs = mem::take(&mut candidate.match_pairs);
if let [MatchPair { pattern: Pat { kind: PatKind::Or { pats }, .. }, place }] =
&*match_pairs
{
existing_bindings.extend_from_slice(&new_bindings);
mem::swap(&mut candidate.bindings, &mut existing_bindings);
candidate.subcandidates = self.create_or_subcandidates(candidate, place, pats);
return true;
}
let mut changed = false;
for match_pair in match_pairs {
match self.simplify_match_pair(match_pair, candidate) {
Ok(()) => {
changed = true;
}
Err(match_pair) => {
candidate.match_pairs.push(match_pair);
}
}
}
// Avoid issue #69971: the binding order should be right to left if there are more
// bindings after `@` to please the borrow checker
// Ex
// struct NonCopyStruct { // struct NonCopyStruct {
// copy_field: u32, // copy_field: u32,
// } // }
@ -99,23 +54,67 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// let z = x.copy_field; // let z = x.copy_field;
// let y = x; // let y = x;
// } // }
candidate.bindings.extend_from_slice(&new_bindings); //
mem::swap(&mut candidate.bindings, &mut new_bindings); // We can't just reverse the binding order, because we must preserve pattern-order
// otherwise, e.g. in `let (Some(a), Some(b)) = (x, y)`. Our rule then is: deepest-first,
// and bindings at the same depth stay in source order.
//
// To do this, every time around the loop we prepend the newly found bindings to the
// bindings we already had.
//
// example:
// candidate.bindings = [1, 2, 3]
// bindings in iter 1: [4, 5]
// bindings in iter 2: [6, 7]
//
// final bindings: [6, 7, 4, 5, 1, 2, 3]
let mut accumulated_bindings = mem::take(&mut candidate.bindings);
// Repeatedly simplify match pairs until fixed point is reached
loop {
let mut changed = false;
for match_pair in mem::take(&mut candidate.match_pairs) {
match self.simplify_match_pair(match_pair, candidate) {
Ok(()) => {
changed = true;
}
Err(match_pair) => {
candidate.match_pairs.push(match_pair);
}
}
}
// This does: accumulated_bindings = candidate.bindings.take() ++ accumulated_bindings
candidate.bindings.extend_from_slice(&accumulated_bindings);
mem::swap(&mut candidate.bindings, &mut accumulated_bindings);
candidate.bindings.clear(); candidate.bindings.clear();
if !changed { if !changed {
existing_bindings.extend_from_slice(&new_bindings); // If we were not able to simplify anymore, done.
mem::swap(&mut candidate.bindings, &mut existing_bindings); break;
}
}
// Store computed bindings back in `candidate`.
mem::swap(&mut candidate.bindings, &mut accumulated_bindings);
let did_expand_or =
if let [MatchPair { pattern: Pat { kind: PatKind::Or { pats }, .. }, place }] =
&*candidate.match_pairs
{
candidate.subcandidates = self.create_or_subcandidates(candidate, place, pats);
candidate.match_pairs.clear();
true
} else {
false
};
// Move or-patterns to the end, because they can result in us // Move or-patterns to the end, because they can result in us
// creating additional candidates, so we want to test them as // creating additional candidates, so we want to test them as
// late as possible. // late as possible.
candidate candidate.match_pairs.sort_by_key(|pair| matches!(pair.pattern.kind, PatKind::Or { .. }));
.match_pairs
.sort_by_key(|pair| matches!(pair.pattern.kind, PatKind::Or { .. }));
debug!(simplified = ?candidate, "simplify_candidate"); debug!(simplified = ?candidate, "simplify_candidate");
return false; // if we were not able to simplify any, done.
} did_expand_or
}
} }
/// Given `candidate` that has a single or-pattern for its match-pairs, /// Given `candidate` that has a single or-pattern for its match-pairs,

View file

@ -51,13 +51,13 @@
- } - }
- -
- bb3: { - bb3: {
StorageLive(_8);
_8 = (((_3.0: std::option::Option<u32>) as Some).0: u32);
StorageLive(_9); StorageLive(_9);
_9 = (((_3.1: std::option::Option<u32>) as Some).0: u32); _9 = (((_3.1: std::option::Option<u32>) as Some).0: u32);
StorageLive(_8);
_8 = (((_3.0: std::option::Option<u32>) as Some).0: u32);
_0 = const 0_u32; _0 = const 0_u32;
StorageDead(_9);
StorageDead(_8); StorageDead(_8);
StorageDead(_9);
- goto -> bb4; - goto -> bb4;
+ goto -> bb3; + goto -> bb3;
} }

View file

@ -58,13 +58,13 @@
- -
- bb4: { - bb4: {
+ bb2: { + bb2: {
StorageLive(_9);
_9 = (((_3.0: std::option::Option<u32>) as Some).0: u32);
StorageLive(_10); StorageLive(_10);
_10 = (((_3.1: std::option::Option<u32>) as Some).0: u32); _10 = (((_3.1: std::option::Option<u32>) as Some).0: u32);
StorageLive(_9);
_9 = (((_3.0: std::option::Option<u32>) as Some).0: u32);
_0 = const 0_u32; _0 = const 0_u32;
StorageDead(_10);
StorageDead(_9); StorageDead(_9);
StorageDead(_10);
- goto -> bb6; - goto -> bb6;
+ goto -> bb4; + goto -> bb4;
} }

View file

@ -51,13 +51,13 @@
- } - }
- -
- bb3: { - bb3: {
StorageLive(_8);
_8 = (((_3.0: std::option::Option<u32>) as Some).0: u32);
StorageLive(_9); StorageLive(_9);
_9 = (((_3.1: std::option::Option<bool>) as Some).0: bool); _9 = (((_3.1: std::option::Option<bool>) as Some).0: bool);
StorageLive(_8);
_8 = (((_3.0: std::option::Option<u32>) as Some).0: u32);
_0 = const 0_u32; _0 = const 0_u32;
StorageDead(_9);
StorageDead(_8); StorageDead(_8);
StorageDead(_9);
- goto -> bb4; - goto -> bb4;
+ goto -> bb3; + goto -> bb3;
} }

View file

@ -69,16 +69,16 @@
- bb4: { - bb4: {
+ bb3: { + bb3: {
StorageLive(_11);
_11 = (((_4.0: std::option::Option<u32>) as Some).0: u32);
StorageLive(_12);
_12 = (((_4.1: std::option::Option<u32>) as Some).0: u32);
StorageLive(_13); StorageLive(_13);
_13 = (((_4.2: std::option::Option<u32>) as Some).0: u32); _13 = (((_4.2: std::option::Option<u32>) as Some).0: u32);
StorageLive(_12);
_12 = (((_4.1: std::option::Option<u32>) as Some).0: u32);
StorageLive(_11);
_11 = (((_4.0: std::option::Option<u32>) as Some).0: u32);
_0 = const 0_u32; _0 = const 0_u32;
StorageDead(_13);
StorageDead(_12);
StorageDead(_11); StorageDead(_11);
StorageDead(_12);
StorageDead(_13);
- goto -> bb5; - goto -> bb5;
+ goto -> bb4; + goto -> bb4;
} }

View file

@ -116,12 +116,12 @@
} }
bb6: { bb6: {
StorageLive(_12);
_39 = deref_copy (_4.0: &ViewportPercentageLength);
_12 = (((*_39) as Vw).0: f32);
StorageLive(_13); StorageLive(_13);
_40 = deref_copy (_4.1: &ViewportPercentageLength); _39 = deref_copy (_4.1: &ViewportPercentageLength);
_13 = (((*_40) as Vw).0: f32); _13 = (((*_39) as Vw).0: f32);
StorageLive(_12);
_40 = deref_copy (_4.0: &ViewportPercentageLength);
_12 = (((*_40) as Vw).0: f32);
StorageLive(_14); StorageLive(_14);
StorageLive(_15); StorageLive(_15);
_15 = _12; _15 = _12;
@ -132,18 +132,18 @@
StorageDead(_15); StorageDead(_15);
_3 = ViewportPercentageLength::Vw(move _14); _3 = ViewportPercentageLength::Vw(move _14);
StorageDead(_14); StorageDead(_14);
StorageDead(_13);
StorageDead(_12); StorageDead(_12);
StorageDead(_13);
goto -> bb10; goto -> bb10;
} }
bb7: { bb7: {
StorageLive(_17);
_41 = deref_copy (_4.0: &ViewportPercentageLength);
_17 = (((*_41) as Vh).0: f32);
StorageLive(_18); StorageLive(_18);
_42 = deref_copy (_4.1: &ViewportPercentageLength); _41 = deref_copy (_4.1: &ViewportPercentageLength);
_18 = (((*_42) as Vh).0: f32); _18 = (((*_41) as Vh).0: f32);
StorageLive(_17);
_42 = deref_copy (_4.0: &ViewportPercentageLength);
_17 = (((*_42) as Vh).0: f32);
StorageLive(_19); StorageLive(_19);
StorageLive(_20); StorageLive(_20);
_20 = _17; _20 = _17;
@ -154,18 +154,18 @@
StorageDead(_20); StorageDead(_20);
_3 = ViewportPercentageLength::Vh(move _19); _3 = ViewportPercentageLength::Vh(move _19);
StorageDead(_19); StorageDead(_19);
StorageDead(_18);
StorageDead(_17); StorageDead(_17);
StorageDead(_18);
goto -> bb10; goto -> bb10;
} }
bb8: { bb8: {
StorageLive(_22);
_43 = deref_copy (_4.0: &ViewportPercentageLength);
_22 = (((*_43) as Vmin).0: f32);
StorageLive(_23); StorageLive(_23);
_44 = deref_copy (_4.1: &ViewportPercentageLength); _43 = deref_copy (_4.1: &ViewportPercentageLength);
_23 = (((*_44) as Vmin).0: f32); _23 = (((*_43) as Vmin).0: f32);
StorageLive(_22);
_44 = deref_copy (_4.0: &ViewportPercentageLength);
_22 = (((*_44) as Vmin).0: f32);
StorageLive(_24); StorageLive(_24);
StorageLive(_25); StorageLive(_25);
_25 = _22; _25 = _22;
@ -176,18 +176,18 @@
StorageDead(_25); StorageDead(_25);
_3 = ViewportPercentageLength::Vmin(move _24); _3 = ViewportPercentageLength::Vmin(move _24);
StorageDead(_24); StorageDead(_24);
StorageDead(_23);
StorageDead(_22); StorageDead(_22);
StorageDead(_23);
goto -> bb10; goto -> bb10;
} }
bb9: { bb9: {
StorageLive(_27);
_45 = deref_copy (_4.0: &ViewportPercentageLength);
_27 = (((*_45) as Vmax).0: f32);
StorageLive(_28); StorageLive(_28);
_46 = deref_copy (_4.1: &ViewportPercentageLength); _45 = deref_copy (_4.1: &ViewportPercentageLength);
_28 = (((*_46) as Vmax).0: f32); _28 = (((*_45) as Vmax).0: f32);
StorageLive(_27);
_46 = deref_copy (_4.0: &ViewportPercentageLength);
_27 = (((*_46) as Vmax).0: f32);
StorageLive(_29); StorageLive(_29);
StorageLive(_30); StorageLive(_30);
_30 = _27; _30 = _27;
@ -198,8 +198,8 @@
StorageDead(_30); StorageDead(_30);
_3 = ViewportPercentageLength::Vmax(move _29); _3 = ViewportPercentageLength::Vmax(move _29);
StorageDead(_29); StorageDead(_29);
StorageDead(_28);
StorageDead(_27); StorageDead(_27);
StorageDead(_28);
goto -> bb10; goto -> bb10;
} }

View file

@ -59,13 +59,13 @@
} }
bb5: { bb5: {
StorageLive(_9);
_9 = (((_3.0: std::option::Option<u32>) as Some).0: u32);
StorageLive(_10); StorageLive(_10);
_10 = (((_3.1: std::option::Option<u32>) as Some).0: u32); _10 = (((_3.1: std::option::Option<u32>) as Some).0: u32);
StorageLive(_9);
_9 = (((_3.0: std::option::Option<u32>) as Some).0: u32);
_0 = const 0_u32; _0 = const 0_u32;
StorageDead(_10);
StorageDead(_9); StorageDead(_9);
StorageDead(_10);
goto -> bb8; goto -> bb8;
} }

View file

@ -1,13 +1,30 @@
// run-pass // run-pass
#![allow(unused)]
// Test copy // Test copy
struct A { a: i32, b: i32 } struct A {
struct B { a: i32, b: C } a: i32,
struct D { a: i32, d: C } b: i32,
#[derive(Copy,Clone)] }
struct C { c: i32 } struct B {
a: i32,
b: C,
}
struct D {
a: i32,
d: C,
}
#[derive(Copy, Clone)]
struct C {
c: i32,
}
enum E {
E { a: i32, e: C },
NotE,
}
#[rustfmt::skip]
pub fn main() { pub fn main() {
match (A {a: 10, b: 20}) { match (A {a: 10, b: 20}) {
x@A {a, b: 20} => { assert!(x.a == 10); assert!(a == 10); } x@A {a, b: 20} => { assert!(x.a == 10); assert!(a == 10); }
@ -23,6 +40,23 @@ pub fn main() {
y.d.c = 30; y.d.c = 30;
assert_eq!(d.c, 20); assert_eq!(d.c, 20);
match (E::E { a: 10, e: C { c: 20 } }) {
x @ E::E{ a, e: C { c } } => {
assert!(matches!(x, E::E { a: 10, e: C { c: 20 } }));
assert!(a == 10);
assert!(c == 20);
}
_ => panic!(),
}
match (E::E { a: 10, e: C { c: 20 } }) {
mut x @ E::E{ a, e: C { mut c } } => {
x = E::NotE;
c += 30;
assert_eq!(c, 50);
}
_ => panic!(),
}
let some_b = Some(B { a: 10, b: C { c: 20 } }); let some_b = Some(B { a: 10, b: C { c: 20 } });
// in irrefutable pattern // in irrefutable pattern

View file

@ -15,8 +15,8 @@ fn main() {
let a @ (b, c) = (u(), u()); //~ ERROR use of partially moved value let a @ (b, c) = (u(), u()); //~ ERROR use of partially moved value
match Ok(U) { match Ok(U) {
a @ Ok(b) | a @ Err(b) => {} //~ ERROR use of moved value a @ Ok(b) | a @ Err(b) => {} //~ ERROR use of partially moved value
//~^ ERROR use of moved value //~^ ERROR use of partially moved value
} }
fn fun(a @ b: U) {} //~ ERROR use of moved value fn fun(a @ b: U) {} //~ ERROR use of moved value

View file

@ -40,35 +40,33 @@ help: borrow this binding in the pattern to avoid moving the value
LL | let ref a @ (b, ref c) = (u(), u()); LL | let ref a @ (b, ref c) = (u(), u());
| +++ +++ | +++ +++
error[E0382]: use of moved value error[E0382]: use of partially moved value
--> $DIR/borrowck-move-and-move.rs:18:16 --> $DIR/borrowck-move-and-move.rs:18:9
| |
LL | match Ok(U) {
| ----- move occurs because value has type `Result<U, U>`, which does not implement the `Copy` trait
LL | a @ Ok(b) | a @ Err(b) => {} LL | a @ Ok(b) | a @ Err(b) => {}
| - ^ value used here after move | ^ - value partially moved here
| | | |
| value moved here | value used here after partial move
| |
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
help: borrow this binding in the pattern to avoid moving the value help: borrow this binding in the pattern to avoid moving the value
| |
LL | ref a @ Ok(b) | a @ Err(b) => {} LL | ref a @ Ok(ref b) | a @ Err(b) => {}
| +++ | +++ +++
error[E0382]: use of moved value error[E0382]: use of partially moved value
--> $DIR/borrowck-move-and-move.rs:18:29 --> $DIR/borrowck-move-and-move.rs:18:21
| |
LL | match Ok(U) {
| ----- move occurs because value has type `Result<U, U>`, which does not implement the `Copy` trait
LL | a @ Ok(b) | a @ Err(b) => {} LL | a @ Ok(b) | a @ Err(b) => {}
| - ^ value used here after move | ^ - value partially moved here
| | | |
| value moved here | value used here after partial move
| |
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
help: borrow this binding in the pattern to avoid moving the value help: borrow this binding in the pattern to avoid moving the value
| |
LL | a @ Ok(b) | ref a @ Err(b) => {} LL | a @ Ok(b) | ref a @ Err(ref b) => {}
| +++ | +++ +++
error[E0382]: use of partially moved value error[E0382]: use of partially moved value
--> $DIR/borrowck-move-and-move.rs:25:9 --> $DIR/borrowck-move-and-move.rs:25:9

View file

@ -48,19 +48,17 @@ fn main() {
//~^ ERROR borrow of moved value //~^ ERROR borrow of moved value
//~| ERROR borrow of moved value //~| ERROR borrow of moved value
//~| ERROR borrow of moved value //~| ERROR borrow of moved value
//~| ERROR use of moved value //~| ERROR use of partially moved value
None => {} None => {}
} }
match Some([U, U]) { match Some([U, U]) {
mut a @ Some([ref b, ref mut c]) => {} mut a @ Some([ref b, ref mut c]) => {}
//~^ ERROR borrow of moved value //~^ ERROR borrow of moved value
//~| ERROR borrow of moved value
None => {} None => {}
} }
match Some(u()) { match Some(u()) {
a @ Some(ref b) => {} a @ Some(ref b) => {}
//~^ ERROR borrow of moved value //~^ ERROR borrow of moved value
//~| ERROR borrow of moved value
None => {} None => {}
} }
match Some((u(), u())) { match Some((u(), u())) {
@ -68,13 +66,12 @@ fn main() {
//~^ ERROR borrow of moved value //~^ ERROR borrow of moved value
//~| ERROR borrow of moved value //~| ERROR borrow of moved value
//~| ERROR borrow of moved value //~| ERROR borrow of moved value
//~| ERROR use of moved value //~| ERROR use of partially moved value
None => {} None => {}
} }
match Some([u(), u()]) { match Some([u(), u()]) {
mut a @ Some([ref b, ref mut c]) => {} mut a @ Some([ref b, ref mut c]) => {}
//~^ ERROR borrow of moved value //~^ ERROR borrow of moved value
//~| ERROR borrow of moved value
None => {} None => {}
} }
} }

View file

@ -215,7 +215,7 @@ LL | ref mut a @ Some([ref b, ref mut c]) => {}
| +++ | +++
error: borrow of moved value error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:9 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:60:9
| |
LL | a @ Some(ref b) => {} LL | a @ Some(ref b) => {}
| ^ ----- value borrowed here after move | ^ ----- value borrowed here after move
@ -229,7 +229,7 @@ LL | ref a @ Some(ref b) => {}
| +++ | +++
error: borrow of moved value error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:9 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:65:9
| |
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| ^ --------- ----- value borrowed here after move | ^ --------- ----- value borrowed here after move
@ -244,7 +244,7 @@ LL | ref a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| +++ | +++
error: borrow of moved value error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:19 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:65:19
| |
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| ^^^^^ --------- value borrowed here after move | ^^^^^ --------- value borrowed here after move
@ -258,7 +258,7 @@ LL | a @ Some((ref mut b @ ref mut c, d @ ref e)) => {}
| +++ | +++
error: borrow of moved value error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:38 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:65:38
| |
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| ^ ----- value borrowed here after move | ^ ----- value borrowed here after move
@ -272,7 +272,7 @@ LL | a @ Some((mut b @ ref mut c, ref d @ ref e)) => {}
| +++ | +++
error: borrow of moved value error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:75:9 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:73:9
| |
LL | mut a @ Some([ref b, ref mut c]) => {} LL | mut a @ Some([ref b, ref mut c]) => {}
| ^^^^^ ----- --------- value borrowed here after move | ^^^^^ ----- --------- value borrowed here after move
@ -314,66 +314,33 @@ help: borrow this binding in the pattern to avoid moving the value
LL | let ref a @ (mut b @ ref mut c, ref d @ ref e) = (u(), u()); LL | let ref a @ (mut b @ ref mut c, ref d @ ref e) = (u(), u());
| +++ +++ | +++ +++
error[E0382]: use of moved value error[E0382]: use of partially moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:47:38 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:47:9
| |
LL | match Some((U, U)) {
| ------------ move occurs because value has type `Option<(U, U)>`, which does not implement the `Copy` trait
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| - value moved here ^ value used here after move | ^ - value partially moved here
| |
| value used here after partial move
| |
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
help: borrow this binding in the pattern to avoid moving the value help: borrow this binding in the pattern to avoid moving the value
| |
LL | ref a @ Some((mut b @ ref mut c, d @ ref e)) => {} LL | ref a @ Some((mut b @ ref mut c, ref d @ ref e)) => {}
| +++ | +++ +++
error[E0382]: borrow of moved value error[E0382]: use of partially moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:55:30 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:65:9
| |
LL | match Some([U, U]) {
| ------------ move occurs because value has type `Option<[U; 2]>`, which does not implement the `Copy` trait
LL | mut a @ Some([ref b, ref mut c]) => {}
| ----- ^^^^^^^^^ value borrowed here after move
| |
| value moved here
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:18
|
LL | match Some(u()) {
| --------- move occurs because value has type `Option<U>`, which does not implement the `Copy` trait
LL | a @ Some(ref b) => {}
| - ^^^^^ value borrowed here after move
| |
| value moved here
|
help: borrow this binding in the pattern to avoid moving the value
|
LL | ref a @ Some(ref b) => {}
| +++
error[E0382]: use of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:38
|
LL | match Some((u(), u())) {
| ---------------- move occurs because value has type `Option<(U, U)>`, which does not implement the `Copy` trait
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| - value moved here ^ value used here after move | ^ - value partially moved here
| |
| value used here after partial move
| |
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
help: borrow this binding in the pattern to avoid moving the value help: borrow this binding in the pattern to avoid moving the value
| |
LL | ref a @ Some((mut b @ ref mut c, d @ ref e)) => {} LL | ref a @ Some((mut b @ ref mut c, ref d @ ref e)) => {}
| +++ | +++ +++
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:75:30
|
LL | match Some([u(), u()]) {
| ---------------- move occurs because value has type `Option<[U; 2]>`, which does not implement the `Copy` trait
LL | mut a @ Some([ref b, ref mut c]) => {}
| ----- ^^^^^^^^^ value borrowed here after move
| |
| value moved here
error: borrow of moved value error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:11:11 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:11:11
@ -457,6 +424,6 @@ help: borrow this binding in the pattern to avoid moving the value
LL | fn f3(ref a @ [ref mut b, ref c]: [U; 2]) {} LL | fn f3(ref a @ [ref mut b, ref c]: [U; 2]) {}
| +++ | +++
error: aborting due to 33 previous errors error: aborting due to 30 previous errors
For more information about this error, try `rustc --explain E0382`. For more information about this error, try `rustc --explain E0382`.

View file

@ -58,11 +58,13 @@ fn main() {
match Some([U, U]) { match Some([U, U]) {
ref mut a @ Some([b, mut c]) => {} ref mut a @ Some([b, mut c]) => {}
//~^ ERROR cannot move out of value because it is borrowed //~^ ERROR cannot move out of value because it is borrowed
//~| ERROR borrow of partially moved value
None => {} None => {}
} }
match Some(u()) { match Some(u()) {
ref a @ Some(b) => {} ref a @ Some(b) => {}
//~^ ERROR cannot move out of value because it is borrowed //~^ ERROR cannot move out of value because it is borrowed
//~| ERROR borrow of partially moved value
None => {} None => {}
} }
match Some((u(), u())) { match Some((u(), u())) {
@ -77,6 +79,7 @@ fn main() {
match Some([u(), u()]) { match Some([u(), u()]) {
ref mut a @ Some([b, mut c]) => {} ref mut a @ Some([b, mut c]) => {}
//~^ ERROR cannot move out of value because it is borrowed //~^ ERROR cannot move out of value because it is borrowed
//~| ERROR borrow of partially moved value
None => {} None => {}
} }
} }

View file

@ -125,7 +125,7 @@ LL | ref mut a @ Some([b, mut c]) => {}
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:64:9 --> $DIR/borrowck-pat-by-move-and-ref.rs:65:9
| |
LL | ref a @ Some(b) => {} LL | ref a @ Some(b) => {}
| ^^^^^ - value is moved into `b` here | ^^^^^ - value is moved into `b` here
@ -133,7 +133,7 @@ LL | ref a @ Some(b) => {}
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:69:9 --> $DIR/borrowck-pat-by-move-and-ref.rs:71:9
| |
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| ^^^^^ ----- - value is moved into `e` here | ^^^^^ ----- - value is moved into `e` here
@ -142,7 +142,7 @@ LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:69:23 --> $DIR/borrowck-pat-by-move-and-ref.rs:71:23
| |
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| ^^^^^ ----- value is moved into `c` here | ^^^^^ ----- value is moved into `c` here
@ -150,7 +150,7 @@ LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| value is borrowed by `b` here | value is borrowed by `b` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:69:38 --> $DIR/borrowck-pat-by-move-and-ref.rs:71:38
| |
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| ^^^^^ - value is moved into `e` here | ^^^^^ - value is moved into `e` here
@ -158,7 +158,7 @@ LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| value is borrowed by `d` here | value is borrowed by `d` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:78:9 --> $DIR/borrowck-pat-by-move-and-ref.rs:80:9
| |
LL | ref mut a @ Some([b, mut c]) => {} LL | ref mut a @ Some([b, mut c]) => {}
| ^^^^^^^^^ - ----- value is moved into `c` here | ^^^^^^^^^ - ----- value is moved into `c` here
@ -236,8 +236,36 @@ help: borrow this binding in the pattern to avoid moving the value
LL | let ref mut a @ [b, ref mut c] = [u(), u()]; LL | let ref mut a @ [b, ref mut c] = [u(), u()];
| +++ | +++
error[E0382]: borrow of partially moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:59:9
|
LL | ref mut a @ Some([b, mut c]) => {}
| ^^^^^^^^^ ----- value partially moved here
| |
| value borrowed here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
help: borrow this binding in the pattern to avoid moving the value
|
LL | ref mut a @ Some([b, ref mut c]) => {}
| +++
error[E0382]: borrow of partially moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:65:9
|
LL | ref a @ Some(b) => {}
| ^^^^^ - value partially moved here
| |
| value borrowed here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
help: borrow this binding in the pattern to avoid moving the value
|
LL | ref a @ Some(ref b) => {}
| +++
error[E0382]: borrow of moved value error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:69:23 --> $DIR/borrowck-pat-by-move-and-ref.rs:71:23
| |
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| ^^^^^ ----- value moved here | ^^^^^ ----- value moved here
@ -251,7 +279,7 @@ LL | ref a @ Some((ref b @ ref mut c, ref d @ e)) => {}
| +++ | +++
error[E0382]: borrow of moved value error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:69:38 --> $DIR/borrowck-pat-by-move-and-ref.rs:71:38
| |
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| ^^^^^ - value moved here | ^^^^^ - value moved here
@ -264,6 +292,20 @@ help: borrow this binding in the pattern to avoid moving the value
LL | ref a @ Some((ref b @ mut c, ref d @ ref e)) => {} LL | ref a @ Some((ref b @ mut c, ref d @ ref e)) => {}
| +++ | +++
error[E0382]: borrow of partially moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:80:9
|
LL | ref mut a @ Some([b, mut c]) => {}
| ^^^^^^^^^ ----- value partially moved here
| |
| value borrowed here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
help: borrow this binding in the pattern to avoid moving the value
|
LL | ref mut a @ Some([b, ref mut c]) => {}
| +++
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:11:11 --> $DIR/borrowck-pat-by-move-and-ref.rs:11:11
| |
@ -345,6 +387,6 @@ LL | fn f3(ref mut a @ [b, mut c]: [U; 2]) {}
| |
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
error: aborting due to 36 previous errors error: aborting due to 39 previous errors
For more information about this error, try `rustc --explain E0382`. For more information about this error, try `rustc --explain E0382`.

View file

@ -7,7 +7,7 @@ fn main() {
match &mut Some(1) { match &mut Some(1) {
ref mut z @ &mut Some(ref a) => { ref mut z @ &mut Some(ref a) => {
//~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable
//~| ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
**z = None; **z = None;
println!("{}", *a); println!("{}", *a);
} }
@ -76,8 +76,8 @@ fn main() {
ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
//~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
//~| ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
//~| ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
//~| ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
*b = U; *b = U;
drop(a); drop(a);
} }
@ -87,6 +87,8 @@ fn main() {
ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
//~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
//~| ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
//~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
//~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
//~| ERROR cannot assign to `*b`, as it is immutable for the pattern guard //~| ERROR cannot assign to `*b`, as it is immutable for the pattern guard
_ => {} _ => {}
} }
@ -101,6 +103,8 @@ fn main() {
ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
//~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
//~| ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
//~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
//~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
//~| ERROR cannot move out of `b` in pattern guard //~| ERROR cannot move out of `b` in pattern guard
//~| ERROR cannot move out of `b` in pattern guard //~| ERROR cannot move out of `b` in pattern guard
_ => {} _ => {}

View file

@ -138,7 +138,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false }
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as immutable because it is also borrowed as mutable error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:94:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96:9
| |
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
| ^^^^^^^^^ ----- value is borrowed by `b` here | ^^^^^^^^^ ----- value is borrowed by `b` here
@ -146,7 +146,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as immutable because it is also borrowed as mutable error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:94:33 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96:33
| |
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
| ^^^^^^^^^ ----- value is borrowed by `b` here | ^^^^^^^^^ ----- value is borrowed by `b` here
@ -154,7 +154,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:101:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:9
| |
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
| ^^^^^ --------- value is mutably borrowed by `b` here | ^^^^^ --------- value is mutably borrowed by `b` here
@ -162,7 +162,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:101:33 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:33
| |
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
| ^^^^^ --------- value is mutably borrowed by `b` here | ^^^^^ --------- value is mutably borrowed by `b` here
@ -170,7 +170,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as immutable because it is also borrowed as mutable error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:109:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:113:9
| |
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
| ^^^^^^^^^ ----- value is borrowed by `b` here | ^^^^^^^^^ ----- value is borrowed by `b` here
@ -178,7 +178,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as immutable because it is also borrowed as mutable error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:109:33 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:113:33
| |
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
| ^^^^^^^^^ ----- value is borrowed by `b` here | ^^^^^^^^^ ----- value is borrowed by `b` here
@ -186,7 +186,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:117:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:121:9
| |
LL | let ref a @ (ref mut b, ref mut c) = (U, U); LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| ^^^^^ --------- --------- value is mutably borrowed by `c` here | ^^^^^ --------- --------- value is mutably borrowed by `c` here
@ -195,7 +195,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:123:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:9
| |
LL | let ref a @ (ref mut b, ref mut c) = (U, U); LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| ^^^^^ --------- --------- value is mutably borrowed by `c` here | ^^^^^ --------- --------- value is mutably borrowed by `c` here
@ -204,7 +204,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:129:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:133:9
| |
LL | let ref a @ (ref mut b, ref mut c) = (U, U); LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| ^^^^^ --------- --------- value is mutably borrowed by `c` here | ^^^^^ --------- --------- value is mutably borrowed by `c` here
@ -213,7 +213,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as immutable because it is also borrowed as mutable error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:134:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:138:9
| |
LL | let ref mut a @ (ref b, ref c) = (U, U); LL | let ref mut a @ (ref b, ref c) = (U, U);
| ^^^^^^^^^ ----- ----- value is borrowed by `c` here | ^^^^^^^^^ ----- ----- value is borrowed by `c` here
@ -221,16 +221,16 @@ LL | let ref mut a @ (ref b, ref c) = (U, U);
| | value is borrowed by `b` here | | value is borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:8:31 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:8:9
| |
LL | ref mut z @ &mut Some(ref a) => { LL | ref mut z @ &mut Some(ref a) => {
| --------- ^^^^^ immutable borrow occurs here | ^^^^^^^^^ ----- immutable borrow occurs here
| | | |
| mutable borrow occurs here | mutable borrow occurs here
... ...
LL | **z = None; LL | println!("{}", *a);
| ---------- mutable borrow later used here | -- immutable borrow later used here
error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:46:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:46:9
@ -254,27 +254,44 @@ LL | let ref a @ ref mut b = u();
LL | *b = u(); LL | *b = u();
| -------- mutable borrow later used here | -------- mutable borrow later used here
error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:20 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:9
| |
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
| ----- ^^^^^^^^^ mutable borrow occurs here | ^^^^^ --------- mutable borrow occurs here
| | | |
| immutable borrow occurs here | immutable borrow occurs here
... ...
LL | drop(a); LL | *b = U;
| - immutable borrow later used here | ------ mutable borrow later used here
error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:45 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:33
| |
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
| ----- ^^^^^^^^^ mutable borrow occurs here | ^^^^^ --------- mutable borrow occurs here
| | | |
| immutable borrow occurs here | immutable borrow occurs here
... ...
LL | drop(a); LL | *b = U;
| - immutable borrow later used here | ------ mutable borrow later used here
error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:87:9
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
| ^^^^^ --------- mutable borrow occurs here ------ mutable borrow later used here
| |
| immutable borrow occurs here
error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:87:33
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
| ^^^^^ --------- ------ mutable borrow later used here
| | |
| | mutable borrow occurs here
| immutable borrow occurs here
error[E0594]: cannot assign to `*b`, as it is immutable for the pattern guard error[E0594]: cannot assign to `*b`, as it is immutable for the pattern guard
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:87:61 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:87:61
@ -285,15 +302,32 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false }
= note: variables bound in patterns are immutable until the end of the pattern guard = note: variables bound in patterns are immutable until the end of the pattern guard
error[E0594]: cannot assign to `*a`, as it is immutable for the pattern guard error[E0594]: cannot assign to `*a`, as it is immutable for the pattern guard
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:94:61 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96:61
| |
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
| ^^^^^^^^^^^ cannot assign | ^^^^^^^^^^^ cannot assign
| |
= note: variables bound in patterns are immutable until the end of the pattern guard = note: variables bound in patterns are immutable until the end of the pattern guard
error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:9
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
| ^^^^^ --------- mutable borrow occurs here - mutable borrow later used here
| |
| immutable borrow occurs here
error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:33
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
| ^^^^^ --------- - mutable borrow later used here
| | |
| | mutable borrow occurs here
| immutable borrow occurs here
error[E0507]: cannot move out of `b` in pattern guard error[E0507]: cannot move out of `b` in pattern guard
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:101:66 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:66
| |
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
| ^ move occurs because `b` has type `&mut U`, which does not implement the `Copy` trait | ^ move occurs because `b` has type `&mut U`, which does not implement the `Copy` trait
@ -301,7 +335,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
error[E0507]: cannot move out of `b` in pattern guard error[E0507]: cannot move out of `b` in pattern guard
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:101:66 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:66
| |
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
| ^ move occurs because `b` has type `&mut U`, which does not implement the `Copy` trait | ^ move occurs because `b` has type `&mut U`, which does not implement the `Copy` trait
@ -310,7 +344,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0507]: cannot move out of `a` in pattern guard error[E0507]: cannot move out of `a` in pattern guard
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:109:66 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:113:66
| |
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
| ^ move occurs because `a` has type `&mut Result<U, U>`, which does not implement the `Copy` trait | ^ move occurs because `a` has type `&mut Result<U, U>`, which does not implement the `Copy` trait
@ -318,7 +352,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
error[E0507]: cannot move out of `a` in pattern guard error[E0507]: cannot move out of `a` in pattern guard
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:109:66 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:113:66
| |
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
| ^ move occurs because `a` has type `&mut Result<U, U>`, which does not implement the `Copy` trait | ^ move occurs because `a` has type `&mut Result<U, U>`, which does not implement the `Copy` trait
@ -327,7 +361,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:117:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:121:9
| |
LL | let ref a @ (ref mut b, ref mut c) = (U, U); LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| ^^^^^ --------- mutable borrow occurs here | ^^^^^ --------- mutable borrow occurs here
@ -338,7 +372,7 @@ LL | *b = U;
| ------ mutable borrow later used here | ------ mutable borrow later used here
error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:123:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:9
| |
LL | let ref a @ (ref mut b, ref mut c) = (U, U); LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| ^^^^^ --------- mutable borrow occurs here | ^^^^^ --------- mutable borrow occurs here
@ -349,7 +383,7 @@ LL | *b = U;
| ------ mutable borrow later used here | ------ mutable borrow later used here
error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:129:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:133:9
| |
LL | let ref a @ (ref mut b, ref mut c) = (U, U); LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| ^^^^^ --------- mutable borrow occurs here | ^^^^^ --------- mutable borrow occurs here
@ -409,7 +443,7 @@ LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {}
| | value borrowed here after move | | value borrowed here after move
| move occurs because value has type `U`, which does not implement the `Copy` trait | move occurs because value has type `U`, which does not implement the `Copy` trait
error: aborting due to 47 previous errors error: aborting due to 51 previous errors
Some errors have detailed explanations: E0382, E0502, E0507, E0594. Some errors have detailed explanations: E0382, E0502, E0507, E0594.
For more information about an error, try `rustc --explain E0382`. For more information about an error, try `rustc --explain E0382`.

View file

@ -82,6 +82,8 @@ fn main() {
ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
//~^ ERROR cannot borrow value as mutable more than once at a time //~^ ERROR cannot borrow value as mutable more than once at a time
//~| ERROR cannot borrow value as mutable more than once at a time //~| ERROR cannot borrow value as mutable more than once at a time
//~| ERROR cannot borrow value as mutable more than once at a time
//~| ERROR cannot borrow value as mutable more than once at a time
*b = U; *b = U;
} }
} }
@ -89,8 +91,6 @@ fn main() {
ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
//~^ ERROR cannot borrow value as mutable more than once at a time //~^ ERROR cannot borrow value as mutable more than once at a time
//~| ERROR cannot borrow value as mutable more than once at a time //~| ERROR cannot borrow value as mutable more than once at a time
//~| ERROR cannot borrow value as mutable more than once at a time
//~| ERROR cannot borrow value as mutable more than once at a time
*a = Err(U); *a = Err(U);
// FIXME: The binding name value used above makes for problematic diagnostics. // FIXME: The binding name value used above makes for problematic diagnostics.
@ -101,8 +101,6 @@ fn main() {
ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
//~^ ERROR cannot borrow value as mutable more than once at a time //~^ ERROR cannot borrow value as mutable more than once at a time
//~| ERROR cannot borrow value as mutable more than once at a time //~| ERROR cannot borrow value as mutable more than once at a time
//~| ERROR cannot borrow value as mutable more than once at a time
//~| ERROR cannot borrow value as mutable more than once at a time
drop(a); drop(a);
} }
} }

View file

@ -163,7 +163,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:89:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:91:9
| |
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ^^^^^^^^^ --------- value is mutably borrowed by `b` here | ^^^^^^^^^ --------- value is mutably borrowed by `b` here
@ -171,7 +171,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:89:37 --> $DIR/borrowck-pat-ref-mut-twice.rs:91:37
| |
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ^^^^^^^^^ --------- value is mutably borrowed by `b` here | ^^^^^^^^^ --------- value is mutably borrowed by `b` here
@ -217,48 +217,26 @@ LL | *b = U;
| ------ first borrow later used here | ------ first borrow later used here
error[E0499]: cannot borrow value as mutable more than once at a time error[E0499]: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:89:24 --> $DIR/borrowck-pat-ref-mut-twice.rs:82:9
| |
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| --------- ^^^^^^^^^ second mutable borrow occurs here | ^^^^^^^^^ --------- first mutable borrow occurs here
| | | |
| first mutable borrow occurs here | second mutable borrow occurs here
... ...
LL | *a = Err(U); LL | *b = U;
| ----------- first borrow later used here | ------ first borrow later used here
error[E0499]: cannot borrow value as mutable more than once at a time error[E0499]: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:89:53 --> $DIR/borrowck-pat-ref-mut-twice.rs:82:37
| |
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| --------- ^^^^^^^^^ second mutable borrow occurs here | ^^^^^^^^^ --------- first mutable borrow occurs here
| | | |
| first mutable borrow occurs here | second mutable borrow occurs here
... ...
LL | *a = Err(U); LL | *b = U;
| ----------- first borrow later used here | ------ first borrow later used here
error[E0499]: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:101:24
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| --------- ^^^^^^^^^ second mutable borrow occurs here
| |
| first mutable borrow occurs here
...
LL | drop(a);
| - first borrow later used here
error[E0499]: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:101:53
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| --------- ^^^^^^^^^ second mutable borrow occurs here
| |
| first mutable borrow occurs here
...
LL | drop(a);
| - first borrow later used here
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:8:11 --> $DIR/borrowck-pat-ref-mut-twice.rs:8:11
@ -313,7 +291,7 @@ LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {}
| | value borrowed here after move | | value borrowed here after move
| move occurs because value has type `U`, which does not implement the `Copy` trait | move occurs because value has type `U`, which does not implement the `Copy` trait
error: aborting due to 31 previous errors error: aborting due to 29 previous errors
Some errors have detailed explanations: E0382, E0499. Some errors have detailed explanations: E0382, E0499.
For more information about an error, try `rustc --explain E0382`. For more information about an error, try `rustc --explain E0382`.