Auto merge of #68376 - Centril:move-ref-patterns, r=matthewjasper

Initial implementation of `#![feature(move_ref_pattern)]`

Following up on #45600, under the gate `#![feature(move_ref_pattern)]`, `(ref x, mut y)` is allowed subject to restrictions necessary for soundness. The match checking implementation and tests for `#![feature(bindings_after_at)]` is also adjusted as necessary.

Closes #45600.
Tracking issue: #68354.

r? @matthewjasper
This commit is contained in:
bors 2020-02-09 04:01:28 +00:00
commit f8d830b4de
58 changed files with 2841 additions and 857 deletions

View File

@ -1,3 +1,5 @@
#### Note: this error code is no longer emitted by the compiler.
In a pattern, all values that don't implement the `Copy` trait have to be bound
the same way. The goal here is to avoid binding simultaneously by-move and
by-ref.
@ -6,7 +8,9 @@ This limitation may be removed in a future version of Rust.
Erroneous code example:
```compile_fail,E0009
```
#![feature(move_ref_pattern)]
struct X { x: (), }
let x = Some((X { x: () }, X { x: () }));

View File

@ -186,11 +186,25 @@ impl<'a> DiagnosticBuilder<'a> {
/// all, and you just supplied a `Span` to create the diagnostic,
/// then the snippet will just include that `Span`, which is
/// called the primary span.
pub fn span_label<T: Into<String>>(&mut self, span: Span, label: T) -> &mut Self {
pub fn span_label(&mut self, span: Span, label: impl Into<String>) -> &mut Self {
self.0.diagnostic.span_label(span, label);
self
}
/// Labels all the given spans with the provided label.
/// See `span_label` for more information.
pub fn span_labels(
&mut self,
spans: impl IntoIterator<Item = Span>,
label: impl AsRef<str>,
) -> &mut Self {
let label = label.as_ref();
for span in spans {
self.0.diagnostic.span_label(span, label);
}
self
}
forward!(pub fn note_expected_found(
&mut self,
expected_label: &dyn fmt::Display,

View File

@ -535,6 +535,10 @@ declare_features! (
/// For example, you can write `x @ Some(y)`.
(active, bindings_after_at, "1.41.0", Some(65490), None),
/// Allows patterns with concurrent by-move and by-ref bindings.
/// For example, you can write `Foo(a, ref b)` where `a` is by-move and `b` is by-ref.
(active, move_ref_pattern, "1.42.0", Some(68354), None),
/// Allows `impl const Trait for T` syntax.
(active, const_trait_impl, "1.42.0", Some(67792), None),

View File

@ -16,8 +16,7 @@ use rustc_session::lint::builtin::BINDINGS_WITH_VARIANT_NAME;
use rustc_session::lint::builtin::{IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS};
use rustc_session::parse::feature_err;
use rustc_session::Session;
use rustc_span::symbol::sym;
use rustc_span::{MultiSpan, Span};
use rustc_span::{sym, Span};
use syntax::ast::Mutability;
use std::slice;
@ -114,8 +113,10 @@ impl PatCtxt<'_, '_> {
impl<'tcx> MatchVisitor<'_, 'tcx> {
fn check_patterns(&mut self, has_guard: bool, pat: &Pat<'_>) {
check_legality_of_move_bindings(self, has_guard, pat);
check_borrow_conflicts_in_at_patterns(self, pat);
if !self.tcx.features().move_ref_pattern {
check_legality_of_move_bindings(self, has_guard, pat);
}
pat.walk_always(|pat| check_borrow_conflicts_in_at_patterns(self, pat));
if !self.tcx.features().bindings_after_at {
check_legality_of_bindings_in_at_patterns(self, pat);
}
@ -559,6 +560,11 @@ fn maybe_point_at_variant(ty: Ty<'_>, patterns: &[super::Pat<'_>]) -> Vec<Span>
covered
}
/// Check if a by-value binding is by-value. That is, check if the binding's type is not `Copy`.
fn is_binding_by_move(cx: &MatchVisitor<'_, '_>, hir_id: HirId, span: Span) -> bool {
!cx.tables.node_type(hir_id).is_copy_modulo_regions(cx.tcx, cx.param_env, span)
}
/// Check the legality of legality of by-move bindings.
fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: bool, pat: &Pat<'_>) {
let sess = cx.tcx.sess;
@ -589,8 +595,7 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo
pat.walk_always(|p| {
if let hir::PatKind::Binding(.., sub) = &p.kind {
if let Some(ty::BindByValue(_)) = tables.extract_binding_mode(sess, p.hir_id, p.span) {
let pat_ty = tables.node_type(p.hir_id);
if !pat_ty.is_copy_modulo_regions(cx.tcx, cx.param_env, pat.span) {
if is_binding_by_move(cx, p.hir_id, p.span) {
check_move(p, sub.as_deref());
}
}
@ -599,11 +604,11 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo
// Found some bad by-move spans, error!
if !by_move_spans.is_empty() {
let mut err = struct_span_err!(
sess,
MultiSpan::from_spans(by_move_spans.clone()),
E0009,
"cannot bind by-move and by-ref in the same pattern",
let mut err = feature_err(
&sess.parse_sess,
sym::move_ref_pattern,
by_move_spans.clone(),
"binding by-move and by-ref in the same pattern is unstable",
);
for span in by_ref_spans.iter() {
err.span_label(*span, "by-ref pattern here");
@ -615,81 +620,118 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo
}
}
/// Check that there are no borrow conflicts in `binding @ subpat` patterns.
/// Check that there are no borrow or move conflicts in `binding @ subpat` patterns.
///
/// For example, this would reject:
/// - `ref x @ Some(ref mut y)`,
/// - `ref mut x @ Some(ref y)`
/// - `ref mut x @ Some(ref mut y)`.
/// - `ref mut x @ Some(ref y)`,
/// - `ref mut x @ Some(ref mut y)`,
/// - `ref mut? x @ Some(y)`, and
/// - `x @ Some(ref mut? y)`.
///
/// This analysis is *not* subsumed by NLL.
fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat<'_>) {
let tab = cx.tables;
let sess = cx.tcx.sess;
// Get the mutability of `p` if it's by-ref.
let extract_binding_mut = |hir_id, span| match tab.extract_binding_mode(sess, hir_id, span)? {
ty::BindByValue(_) => None,
ty::BindByReference(m) => Some(m),
// Extract `sub` in `binding @ sub`.
let (name, sub) = match &pat.kind {
hir::PatKind::Binding(.., name, Some(sub)) => (*name, sub),
_ => return,
};
pat.walk_always(|pat| {
// Extract `sub` in `binding @ sub`.
let (name, sub) = match &pat.kind {
hir::PatKind::Binding(.., name, Some(sub)) => (*name, sub),
_ => return,
};
let binding_span = pat.span.with_hi(name.span.hi());
// Extract the mutability.
let mut_outer = match extract_binding_mut(pat.hir_id, pat.span) {
None => return,
Some(m) => m,
};
let tables = cx.tables;
let sess = cx.tcx.sess;
// We now have `ref $mut_outer binding @ sub` (semantically).
// Recurse into each binding in `sub` and find mutability conflicts.
let mut conflicts_mut_mut = Vec::new();
let mut conflicts_mut_ref = Vec::new();
sub.each_binding(|_, hir_id, span, _| {
if let Some(mut_inner) = extract_binding_mut(hir_id, span) {
match (mut_outer, mut_inner) {
(Mutability::Not, Mutability::Not) => {}
(Mutability::Mut, Mutability::Mut) => conflicts_mut_mut.push(span),
_ => conflicts_mut_ref.push(span),
// Get the binding move, extract the mutability if by-ref.
let mut_outer = match tables.extract_binding_mode(sess, pat.hir_id, pat.span) {
Some(ty::BindByValue(_)) if is_binding_by_move(cx, pat.hir_id, pat.span) => {
// We have `x @ pat` where `x` is by-move. Reject all borrows in `pat`.
let mut conflicts_ref = Vec::new();
sub.each_binding(|_, hir_id, span, _| {
match tables.extract_binding_mode(sess, hir_id, span) {
Some(ty::BindByValue(_)) | None => {}
Some(ty::BindByReference(_)) => conflicts_ref.push(span),
}
});
if !conflicts_ref.is_empty() {
let occurs_because = format!(
"move occurs because `{}` has type `{}` which does implement the `Copy` trait",
name,
tables.node_type(pat.hir_id),
);
sess.struct_span_err(pat.span, "borrow of moved value")
.span_label(binding_span, format!("value moved into `{}` here", name))
.span_label(binding_span, occurs_because)
.span_labels(conflicts_ref, "value borrowed here after move")
.emit();
}
});
return;
}
Some(ty::BindByValue(_)) | None => return,
Some(ty::BindByReference(m)) => m,
};
// Report errors if any.
let binding_span = pat.span.with_hi(name.span.hi());
if !conflicts_mut_mut.is_empty() {
// Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`.
let msg = &format!("cannot borrow `{}` as mutable more than once at a time", name);
let mut err = sess.struct_span_err(pat.span, msg);
err.span_label(binding_span, "first mutable borrow occurs here");
for sp in conflicts_mut_mut {
err.span_label(sp, "another mutable borrow occurs here");
// We now have `ref $mut_outer binding @ sub` (semantically).
// Recurse into each binding in `sub` and find mutability or move conflicts.
let mut conflicts_move = Vec::new();
let mut conflicts_mut_mut = Vec::new();
let mut conflicts_mut_ref = Vec::new();
sub.each_binding(|_, hir_id, span, name| {
match tables.extract_binding_mode(sess, hir_id, span) {
Some(ty::BindByReference(mut_inner)) => match (mut_outer, mut_inner) {
(Mutability::Not, Mutability::Not) => {} // Both sides are `ref`.
(Mutability::Mut, Mutability::Mut) => conflicts_mut_mut.push((span, name)), // 2x `ref mut`.
_ => conflicts_mut_ref.push((span, name)), // `ref` + `ref mut` in either direction.
},
Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id, span) => {
conflicts_move.push((span, name)) // `ref mut?` + by-move conflict.
}
for sp in conflicts_mut_ref {
err.span_label(sp, "also borrowed as immutable here");
}
err.emit();
} else if !conflicts_mut_ref.is_empty() {
// Report mutability conflicts for e.g. `ref x @ Some(ref mut y)` or the converse.
let (primary, also) = match mut_outer {
Mutability::Mut => ("mutable", "immutable"),
Mutability::Not => ("immutable", "mutable"),
};
let msg = &format!(
"cannot borrow `{}` as {} because it is also borrowed as {}",
name, also, primary,
);
let mut err = sess.struct_span_err(pat.span, msg);
err.span_label(binding_span, &format!("{} borrow occurs here", primary));
for sp in conflicts_mut_ref {
err.span_label(sp, &format!("{} borrow occurs here", also));
}
err.emit();
Some(ty::BindByValue(_)) | None => {} // `ref mut?` + by-copy is fine.
}
});
// Report errors if any.
if !conflicts_mut_mut.is_empty() {
// Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`.
let mut err = sess
.struct_span_err(pat.span, "cannot borrow value as mutable more than once at a time");
err.span_label(binding_span, format!("first mutable borrow, by `{}`, occurs here", name));
for (span, name) in conflicts_mut_mut {
err.span_label(span, format!("another mutable borrow, by `{}`, occurs here", name));
}
for (span, name) in conflicts_mut_ref {
err.span_label(span, format!("also borrowed as immutable, by `{}`, here", name));
}
for (span, name) in conflicts_move {
err.span_label(span, format!("also moved into `{}` here", name));
}
err.emit();
} else if !conflicts_mut_ref.is_empty() {
// Report mutability conflicts for e.g. `ref x @ Some(ref mut y)` or the converse.
let (primary, also) = match mut_outer {
Mutability::Mut => ("mutable", "immutable"),
Mutability::Not => ("immutable", "mutable"),
};
let msg =
format!("cannot borrow value as {} because it is also borrowed as {}", also, primary);
let mut err = sess.struct_span_err(pat.span, &msg);
err.span_label(binding_span, format!("{} borrow, by `{}`, occurs here", primary, name));
for (span, name) in conflicts_mut_ref {
err.span_label(span, format!("{} borrow, by `{}`, occurs here", also, name));
}
for (span, name) in conflicts_move {
err.span_label(span, format!("also moved into `{}` here", name));
}
err.emit();
} else if !conflicts_move.is_empty() {
// Report by-ref and by-move conflicts, e.g. `ref x @ y`.
let mut err =
sess.struct_span_err(pat.span, "cannot move out of value because it is borrowed");
err.span_label(binding_span, format!("value borrowed, by `{}`, here", name));
for (span, name) in conflicts_move {
err.span_label(span, format!("value moved into `{}` here", name));
}
err.emit();
}
}
/// Forbids bindings in `@` patterns. This used to be is necessary for memory safety,

View File

@ -457,6 +457,7 @@ symbols! {
module,
module_path,
more_struct_aliases,
move_ref_pattern,
move_val_init,
movbe_target_feature,
mul_with_overflow,

View File

@ -1,15 +0,0 @@
struct X { x: (), }
impl Drop for X {
fn drop(&mut self) {
println!("destructor runs");
}
}
fn main() {
let x = Some((X { x: () }, X { x: () }));
match x {
Some((ref _y, _z)) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern
None => panic!()
}
}

View File

@ -1,11 +0,0 @@
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-2.rs:12:23
|
LL | Some((ref _y, _z)) => { },
| ------ ^^ by-move pattern here
| |
| by-ref pattern here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0009`.

View File

@ -1,18 +0,0 @@
struct X { x: (), }
impl Drop for X {
fn drop(&mut self) {
println!("destructor runs");
}
}
enum DoubleOption<T,U> { Some2(T,U), None2 }
fn main() {
let x = DoubleOption::Some2(X { x: () }, X { x: () });
match x {
DoubleOption::Some2(ref _y, _z) => { },
//~^ ERROR cannot bind by-move and by-ref in the same pattern
DoubleOption::None2 => panic!()
}
}

View File

@ -1,11 +0,0 @@
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-3.rs:14:37
|
LL | DoubleOption::Some2(ref _y, _z) => { },
| ------ ^^ by-move pattern here
| |
| by-ref pattern here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0009`.

View File

@ -1,15 +0,0 @@
struct X { x: (), }
impl Drop for X {
fn drop(&mut self) {
println!("destructor runs");
}
}
fn main() {
let x = Some((X { x: () }, X { x: () }));
match x {
Some((_y, ref _z)) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern
None => panic!()
}
}

View File

@ -1,11 +0,0 @@
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-4.rs:12:15
|
LL | Some((_y, ref _z)) => { },
| ^^ ------ by-ref pattern here
| |
| by-move pattern here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0009`.

View File

@ -7,6 +7,8 @@
// edition:2018
// ignore-wasm32-bare compiled with panic=abort by default
#![feature(move_ref_pattern)]
#![allow(unused)]
use std::{
@ -227,6 +229,12 @@ async fn subslice_pattern_reassign(a: Rc<Allocator>) {
a.alloc().await;
}
async fn move_ref_pattern(a: Rc<Allocator>) {
let mut tup = (a.alloc().await, a.alloc().await, a.alloc().await, a.alloc().await);
let (ref _a, ref mut _b, _c, mut _d) = tup;
a.alloc().await;
}
fn run_test<F, G>(cx: &mut Context<'_>, ref f: F)
where
F: Fn(Rc<Allocator>) -> G,
@ -322,4 +330,6 @@ fn main() {
run_test(context, |a| subslice_pattern_from_end_with_drop(a, false, true));
run_test(context, |a| subslice_pattern_from_end_with_drop(a, false, false));
run_test(context, |a| subslice_pattern_reassign(a));
run_test(context, |a| move_ref_pattern(a));
}

View File

@ -2,6 +2,7 @@
// ignore-wasm32-bare compiled with panic=abort by default
#![feature(generators, generator_trait, untagged_unions)]
#![feature(move_ref_pattern)]
#![allow(unused_assignments)]
#![allow(unused_variables)]
@ -290,6 +291,11 @@ fn subslice_mixed_min_lengths(a: &Allocator, c: i32) {
}
}
fn move_ref_pattern(a: &Allocator) {
let mut tup = (a.alloc(), a.alloc(), a.alloc(), a.alloc());
let (ref _a, ref mut _b, _c, mut _d) = tup;
}
fn panic_after_return(a: &Allocator) -> Ptr<'_> {
// Panic in the drop of `p` or `q` can leak
let exceptions = vec![8, 9];
@ -453,6 +459,8 @@ fn main() {
run_test(|a| subslice_mixed_min_lengths(a, 6));
run_test(|a| subslice_mixed_min_lengths(a, 7));
run_test(|a| move_ref_pattern(a));
run_test(|a| {
panic_after_return(a);
});

View File

@ -1,9 +0,0 @@
fn main() {
struct X { x: (), }
let x = Some((X { x: () }, X { x: () }));
match x {
Some((y, ref z)) => {},
//~^ ERROR E0009
None => panic!()
}
}

View File

@ -1,11 +0,0 @@
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/E0009.rs:5:15
|
LL | Some((y, ref z)) => {},
| ^ ----- by-ref pattern here
| |
| by-move pattern here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0009`.

View File

@ -1,20 +0,0 @@
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/issue-53840.rs:13:16
|
LL | E::Foo(a, b, ref c) => {}
| ^ ^ ----- by-ref pattern here
| | |
| | by-move pattern here
| by-move pattern here
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/issue-53840.rs:17:14
|
LL | Bar {a, ref b} => {}
| ^ ----- by-ref pattern here
| |
| by-move pattern here
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0009`.

View File

@ -1,4 +1,4 @@
#![feature(slice_patterns, unsized_locals)]
#![feature(unsized_locals)]
struct A;
#[derive(Clone, Copy)]

View File

@ -3,33 +3,38 @@
// where one side is by-ref and the other is by-move.
#![feature(bindings_after_at)]
#![feature(move_ref_pattern)]
struct X { x: () }
struct X {
x: (),
}
fn main() {
let x = Some(X { x: () });
match x {
Some(ref _y @ _z) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern
None => panic!()
Some(ref _y @ _z) => {} //~ ERROR cannot move out of value because it is borrowed
None => panic!(),
}
let x = Some(X { x: () });
match x {
Some(_z @ ref _y) => { }, //~ ERROR cannot bind by-move with sub-bindings
Some(_z @ ref _y) => {}
//~^ ERROR borrow of moved value
None => panic!()
//~| ERROR borrow of moved value
None => panic!(),
}
let mut x = Some(X { x: () });
match x {
Some(ref mut _y @ _z) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern
None => panic!()
Some(ref mut _y @ _z) => {} //~ ERROR cannot move out of value because it is borrowed
None => panic!(),
}
let mut x = Some(X { x: () });
match x {
Some(_z @ ref mut _y) => { }, //~ ERROR cannot bind by-move with sub-bindings
Some(_z @ ref mut _y) => {}
//~^ ERROR borrow of moved value
None => panic!()
//~| ERROR borrow of moved value
None => panic!(),
}
}

View File

@ -1,37 +1,45 @@
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:12:23
error: cannot move out of value because it is borrowed
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:15:14
|
LL | Some(ref _y @ _z) => { },
| ---------^^
LL | Some(ref _y @ _z) => {}
| ------^^^--
| | |
| | by-move pattern here
| by-ref pattern here
| | value moved into `_z` here
| value borrowed, by `_y`, here
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:18:14
error: borrow of moved value
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:21:14
|
LL | Some(_z @ ref _y) => { },
| ^^^^^^^^^^^ binds an already bound by-move value by moving it
LL | Some(_z @ ref _y) => {}
| --^^^------
| | |
| | value borrowed here after move
| value moved into `_z` here
| move occurs because `_z` has type `X` which does implement the `Copy` trait
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:25:27
error: cannot move out of value because it is borrowed
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:29:14
|
LL | Some(ref mut _y @ _z) => { },
| -------------^^
LL | Some(ref mut _y @ _z) => {}
| ----------^^^--
| | |
| | by-move pattern here
| by-ref pattern here
| | value moved into `_z` here
| value borrowed, by `_y`, here
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:31:14
error: borrow of moved value
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:35:14
|
LL | Some(_z @ ref mut _y) => { },
| ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
LL | Some(_z @ ref mut _y) => {}
| --^^^----------
| | |
| | value borrowed here after move
| value moved into `_z` here
| move occurs because `_z` has type `X` which does implement the `Copy` trait
error[E0382]: borrow of moved value
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:18:19
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:21:19
|
LL | Some(_z @ ref _y) => { },
LL | Some(_z @ ref _y) => {}
| -----^^^^^^
| | |
| | value borrowed here after move
@ -40,9 +48,9 @@ LL | Some(_z @ ref _y) => { },
= note: move occurs because value has type `X`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:31:19
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:35:19
|
LL | Some(_z @ ref mut _y) => { },
LL | Some(_z @ ref mut _y) => {}
| -----^^^^^^^^^^
| | |
| | value borrowed here after move
@ -52,5 +60,4 @@ LL | Some(_z @ ref mut _y) => { },
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0007, E0009, E0382.
For more information about an error, try `rustc --explain E0007`.
For more information about this error, try `rustc --explain E0382`.

View File

@ -1,14 +1,14 @@
// See issue #12534.
#![feature(bindings_after_at)]
#![feature(move_ref_pattern)]
fn main() {}
struct A(Box<u8>);
fn f(a @ A(u): A) -> Box<u8> {
//~^ ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
//~^ ERROR use of moved value
drop(a);
u
}

View File

@ -1,11 +1,5 @@
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/bind-by-move-no-subbindings-fun-param.rs:9:6
|
LL | fn f(a @ A(u): A) -> Box<u8> {
| ^^^^^^^^ binds an already bound by-move value by moving it
error[E0382]: use of moved value
--> $DIR/bind-by-move-no-subbindings-fun-param.rs:9:12
--> $DIR/bind-by-move-no-subbindings-fun-param.rs:10:12
|
LL | fn f(a @ A(u): A) -> Box<u8> {
| ------^-
@ -14,7 +8,6 @@ LL | fn f(a @ A(u): A) -> Box<u8> {
| value moved here
| move occurs because value has type `A`, which does not implement the `Copy` trait
error: aborting due to 2 previous errors
error: aborting due to previous error
Some errors have detailed explanations: E0007, E0382.
For more information about an error, try `rustc --explain E0007`.
For more information about this error, try `rustc --explain E0382`.

View File

@ -1,46 +1,34 @@
// Test that moving on both sides of an `@` pattern is not allowed.
#![feature(bindings_after_at)]
#![feature(move_ref_pattern)]
fn main() {
struct U; // Not copy!
// Prevent promotion:
fn u() -> U { U }
fn u() -> U {
U
}
let a @ b = U;
//~^ ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
let a @ b = U; //~ ERROR use of moved value
let a @ (b, c) = (U, U);
//~^ ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
let a @ (b, c) = (U, U); //~ ERROR use of moved value
let a @ (b, c) = (u(), u());
//~^ ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
let a @ (b, c) = (u(), u()); //~ ERROR use of moved value
match Ok(U) {
a @ Ok(b) | a @ Err(b) => {}
//~^ ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
//~| ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
a @ Ok(b) | a @ Err(b) => {} //~ ERROR use of moved value
//~^ ERROR use of moved value
}
fn fun(a @ b: U) {}
//~^ ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
fn fun(a @ b: U) {} //~ ERROR use of moved value
match [u(), u(), u(), u()] {
xs @ [a, .., b] => {}
//~^ ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
xs @ [a, .., b] => {} //~ ERROR use of moved value
}
match [u(), u(), u(), u()] {
xs @ [_, ys @ .., _] => {}
//~^ ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
xs @ [_, ys @ .., _] => {} //~ ERROR use of moved value
}
}

View File

@ -1,53 +1,5 @@
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/borrowck-move-and-move.rs:11:9
|
LL | let a @ b = U;
| ^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/borrowck-move-and-move.rs:15:9
|
LL | let a @ (b, c) = (U, U);
| ^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/borrowck-move-and-move.rs:19:9
|
LL | let a @ (b, c) = (u(), u());
| ^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/borrowck-move-and-move.rs:24:9
|
LL | a @ Ok(b) | a @ Err(b) => {}
| ^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/borrowck-move-and-move.rs:24:21
|
LL | a @ Ok(b) | a @ Err(b) => {}
| ^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/borrowck-move-and-move.rs:36:9
|
LL | xs @ [a, .., b] => {}
| ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/borrowck-move-and-move.rs:42:9
|
LL | xs @ [_, ys @ .., _] => {}
| ^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/borrowck-move-and-move.rs:31:12
|
LL | fn fun(a @ b: U) {}
| ^^^^^ binds an already bound by-move value by moving it
error[E0382]: use of moved value
--> $DIR/borrowck-move-and-move.rs:11:13
--> $DIR/borrowck-move-and-move.rs:14:13
|
LL | let a @ b = U;
| ----^ - move occurs because value has type `main::U`, which does not implement the `Copy` trait
@ -56,7 +8,7 @@ LL | let a @ b = U;
| value moved here
error[E0382]: use of moved value
--> $DIR/borrowck-move-and-move.rs:15:17
--> $DIR/borrowck-move-and-move.rs:16:17
|
LL | let a @ (b, c) = (U, U);
| --------^- ------ move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait
@ -65,7 +17,7 @@ LL | let a @ (b, c) = (U, U);
| value moved here
error[E0382]: use of moved value
--> $DIR/borrowck-move-and-move.rs:19:17
--> $DIR/borrowck-move-and-move.rs:18:17
|
LL | let a @ (b, c) = (u(), u());
| --------^- ---------- move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait
@ -74,7 +26,7 @@ LL | let a @ (b, c) = (u(), u());
| value moved here
error[E0382]: use of moved value
--> $DIR/borrowck-move-and-move.rs:24:16
--> $DIR/borrowck-move-and-move.rs:21:16
|
LL | match Ok(U) {
| ----- move occurs because value has type `std::result::Result<main::U, main::U>`, which does not implement the `Copy` trait
@ -85,7 +37,7 @@ LL | a @ Ok(b) | a @ Err(b) => {}
| value moved here
error[E0382]: use of moved value
--> $DIR/borrowck-move-and-move.rs:24:29
--> $DIR/borrowck-move-and-move.rs:21:29
|
LL | match Ok(U) {
| ----- move occurs because value has type `std::result::Result<main::U, main::U>`, which does not implement the `Copy` trait
@ -96,7 +48,7 @@ LL | a @ Ok(b) | a @ Err(b) => {}
| value moved here
error[E0382]: use of moved value
--> $DIR/borrowck-move-and-move.rs:36:22
--> $DIR/borrowck-move-and-move.rs:28:22
|
LL | match [u(), u(), u(), u()] {
| -------------------- move occurs because value has type `[main::U; 4]`, which does not implement the `Copy` trait
@ -107,7 +59,7 @@ LL | xs @ [a, .., b] => {}
| value moved here
error[E0382]: use of moved value
--> $DIR/borrowck-move-and-move.rs:42:18
--> $DIR/borrowck-move-and-move.rs:32:18
|
LL | match [u(), u(), u(), u()] {
| -------------------- move occurs because value has type `[main::U; 4]`, which does not implement the `Copy` trait
@ -118,7 +70,7 @@ LL | xs @ [_, ys @ .., _] => {}
| value moved here
error[E0382]: use of moved value
--> $DIR/borrowck-move-and-move.rs:31:16
--> $DIR/borrowck-move-and-move.rs:25:16
|
LL | fn fun(a @ b: U) {}
| ----^
@ -127,7 +79,6 @@ LL | fn fun(a @ b: U) {}
| value moved here
| move occurs because value has type `main::U`, which does not implement the `Copy` trait
error: aborting due to 16 previous errors
error: aborting due to 8 previous errors
Some errors have detailed explanations: E0007, E0382.
For more information about an error, try `rustc --explain E0007`.
For more information about this error, try `rustc --explain E0382`.

View File

@ -3,6 +3,7 @@
// Test `@` patterns combined with `box` patterns.
#![feature(bindings_after_at)]
#![feature(move_ref_pattern)]
#![feature(box_patterns)]
#[derive(Copy, Clone)]
@ -72,4 +73,14 @@ fn main() {
}
_ => {}
}
match Box::new([Ok(c()), Err(nc()), Ok(c())]) {
box [Ok(a), ref xs @ .., Err(b)] => {}
_ => {}
}
match [Ok(Box::new(c())), Err(Box::new(nc())), Ok(Box::new(c())), Ok(Box::new(c()))] {
[Ok(box ref a), ref xs @ .., Err(box b), Err(box ref mut c)] => {}
_ => {}
}
}

View File

@ -1,61 +1,62 @@
// Test `@` patterns combined with `box` patterns.
#![feature(bindings_after_at)]
#![feature(move_ref_pattern)]
#![feature(box_patterns)]
#[derive(Copy, Clone)]
struct C;
fn c() -> C { C }
fn c() -> C {
C
}
struct NC;
fn nc() -> NC { NC }
fn nc() -> NC {
NC
}
fn main() {
let a @ box &b = Box::new(&C);
//~^ ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
//~^ ERROR use of moved value
let a @ box b = Box::new(C);
//~^ ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
//~^ ERROR use of moved value
fn f1(a @ box &b: Box<&C>) {}
//~^ ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
//~^ ERROR use of moved value
fn f2(a @ box b: Box<C>) {}
//~^ ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
//~^ ERROR use of moved value
match Box::new(C) { a @ box b => {} }
//~^ ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
match Box::new(C) {
a @ box b => {} //~ ERROR use of moved value
}
let ref a @ box b = Box::new(NC); //~ ERROR cannot bind by-move and by-ref in the same pattern
let ref a @ box b = Box::new(NC); //~ ERROR cannot move out of value because it is borrowed
let ref a @ box ref mut b = Box::new(nc());
//~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable
//~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
let ref a @ box ref mut b = Box::new(NC);
//~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable
//~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
let ref a @ box ref mut b = Box::new(NC);
//~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable
//~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
*b = NC;
let ref a @ box ref mut b = Box::new(NC);
//~^ ERROR cannot borrow `a` 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 `_` as mutable because it is also borrowed as immutable
*b = NC;
drop(a);
let ref mut a @ box ref b = Box::new(NC);
//~^ ERROR cannot borrow `a` 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 `_` as immutable because it is also borrowed as mutable
*a = Box::new(NC);
drop(b);
fn f5(ref mut a @ box ref b: Box<NC>) {
//~^ ERROR cannot borrow `a` 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 `_` as immutable because it is also borrowed as mutable
*a = Box::new(NC);
drop(b);
@ -63,22 +64,10 @@ fn main() {
match Box::new(nc()) {
ref mut a @ box ref b => {
//~^ ERROR cannot borrow `a` 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 `_` as immutable because it is also borrowed as mutable
*a = Box::new(NC);
drop(b);
}
}
match Box::new([Ok(c()), Err(nc()), Ok(c())]) {
box [Ok(a), ref xs @ .., Err(b)] => {}
//~^ ERROR cannot bind by-move and by-ref in the same pattern
_ => {}
}
match [Ok(Box::new(c())), Err(Box::new(nc())), Ok(Box::new(c())), Ok(Box::new(c()))] {
[Ok(box ref a), ref xs @ .., Err(box b), Err(box ref mut c)] => {}
//~^ ERROR cannot bind by-move and by-ref in the same pattern
_ => {}
}
}

View File

@ -1,125 +1,77 @@
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/borrowck-pat-at-and-box.rs:16:9
|
LL | let a @ box &b = Box::new(&C);
| ^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/borrowck-pat-at-and-box.rs:20:9
|
LL | let a @ box b = Box::new(C);
| ^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/borrowck-pat-at-and-box.rs:32:25
|
LL | match Box::new(C) { a @ box b => {} }
| ^^^^^^^^^ binds an already bound by-move value by moving it
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/borrowck-pat-at-and-box.rs:36:21
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-at-and-box.rs:37:9
|
LL | let ref a @ box b = Box::new(NC);
| ------------^
| -----^^^^^^^-
| | |
| | by-move pattern here
| by-ref pattern here
| | value moved into `b` here
| value borrowed, by `a`, here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-at-and-box.rs:38:9
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-at-and-box.rs:39:9
|
LL | let ref a @ box ref mut b = Box::new(nc());
| -----^^^^^^^---------
| | |
| | mutable borrow occurs here
| immutable borrow occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-at-and-box.rs:40:9
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-at-and-box.rs:41:9
|
LL | let ref a @ box ref mut b = Box::new(NC);
| -----^^^^^^^---------
| | |
| | mutable borrow occurs here
| immutable borrow occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-at-and-box.rs:42:9
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-at-and-box.rs:43:9
|
LL | let ref a @ box ref mut b = Box::new(NC);
| -----^^^^^^^---------
| | |
| | mutable borrow occurs here
| immutable borrow occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-at-and-box.rs:45:9
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-at-and-box.rs:46:9
|
LL | let ref a @ box ref mut b = Box::new(NC);
| -----^^^^^^^---------
| | |
| | mutable borrow occurs here
| immutable borrow occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-at-and-box.rs:51:9
error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-at-and-box.rs:52:9
|
LL | let ref mut a @ box ref b = Box::new(NC);
| ---------^^^^^^^-----
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| | immutable borrow, by `b`, occurs here
| mutable borrow, by `a`, occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-at-and-box.rs:65:9
error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-at-and-box.rs:66:9
|
LL | ref mut a @ box ref b => {
| ---------^^^^^^^-----
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| | immutable borrow, by `b`, occurs here
| mutable borrow, by `a`, occurs here
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/borrowck-pat-at-and-box.rs:74:38
|
LL | box [Ok(a), ref xs @ .., Err(b)] => {}
| ----------- ^ by-move pattern here
| |
| by-ref pattern here
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/borrowck-pat-at-and-box.rs:80:46
|
LL | [Ok(box ref a), ref xs @ .., Err(box b), Err(box ref mut c)] => {}
| ----- ----------- ^ --------- by-ref pattern here
| | | |
| | | by-move pattern here
| | by-ref pattern here
| by-ref pattern here
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/borrowck-pat-at-and-box.rs:24:11
|
LL | fn f1(a @ box &b: Box<&C>) {}
| ^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/borrowck-pat-at-and-box.rs:28:11
|
LL | fn f2(a @ box b: Box<C>) {}
| ^^^^^^^^^ binds an already bound by-move value by moving it
error: cannot borrow `a` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-at-and-box.rs:57:11
error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-at-and-box.rs:58:11
|
LL | fn f5(ref mut a @ box ref b: Box<NC>) {
| ---------^^^^^^^-----
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| | immutable borrow, by `b`, occurs here
| mutable borrow, by `a`, occurs here
error[E0382]: use of moved value
--> $DIR/borrowck-pat-at-and-box.rs:16:18
--> $DIR/borrowck-pat-at-and-box.rs:21:18
|
LL | let a @ box &b = Box::new(&C);
| ---------^ ------------ move occurs because value has type `std::boxed::Box<&C>`, which does not implement the `Copy` trait
@ -128,7 +80,7 @@ LL | let a @ box &b = Box::new(&C);
| value moved here
error[E0382]: use of moved value
--> $DIR/borrowck-pat-at-and-box.rs:20:17
--> $DIR/borrowck-pat-at-and-box.rs:24:17
|
LL | let a @ box b = Box::new(C);
| --------^ ----------- move occurs because value has type `std::boxed::Box<C>`, which does not implement the `Copy` trait
@ -137,17 +89,18 @@ LL | let a @ box b = Box::new(C);
| value moved here
error[E0382]: use of moved value
--> $DIR/borrowck-pat-at-and-box.rs:32:33
--> $DIR/borrowck-pat-at-and-box.rs:34:17
|
LL | match Box::new(C) { a @ box b => {} }
| ----------- --------^
| | | |
| | | value used here after move
| | value moved here
| move occurs because value has type `std::boxed::Box<C>`, which does not implement the `Copy` trait
LL | match Box::new(C) {
| ----------- move occurs because value has type `std::boxed::Box<C>`, which does not implement the `Copy` trait
LL | a @ box b => {}
| --------^
| | |
| | value used here after move
| value moved here
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-at-and-box.rs:45:21
--> $DIR/borrowck-pat-at-and-box.rs:46:21
|
LL | let ref a @ box ref mut b = Box::new(NC);
| ------------^^^^^^^^^
@ -159,7 +112,7 @@ LL | drop(a);
| - immutable borrow later used here
error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-at-and-box.rs:51:25
--> $DIR/borrowck-pat-at-and-box.rs:52:25
|
LL | let ref mut a @ box ref b = Box::new(NC);
| ----------------^^^^^
@ -171,7 +124,7 @@ LL | *a = Box::new(NC);
| -- mutable borrow later used here
error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-at-and-box.rs:65:25
--> $DIR/borrowck-pat-at-and-box.rs:66:25
|
LL | ref mut a @ box ref b => {
| ----------------^^^^^
@ -183,7 +136,7 @@ LL | *a = Box::new(NC);
| -- mutable borrow later used here
error[E0382]: use of moved value
--> $DIR/borrowck-pat-at-and-box.rs:24:20
--> $DIR/borrowck-pat-at-and-box.rs:27:20
|
LL | fn f1(a @ box &b: Box<&C>) {}
| ---------^
@ -193,7 +146,7 @@ LL | fn f1(a @ box &b: Box<&C>) {}
| move occurs because value has type `std::boxed::Box<&C>`, which does not implement the `Copy` trait
error[E0382]: use of moved value
--> $DIR/borrowck-pat-at-and-box.rs:28:19
--> $DIR/borrowck-pat-at-and-box.rs:30:19
|
LL | fn f2(a @ box b: Box<C>) {}
| --------^
@ -203,7 +156,7 @@ LL | fn f2(a @ box b: Box<C>) {}
| move occurs because value has type `std::boxed::Box<C>`, which does not implement the `Copy` trait
error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-at-and-box.rs:57:27
--> $DIR/borrowck-pat-at-and-box.rs:58:27
|
LL | fn f5(ref mut a @ box ref b: Box<NC>) {
| ----------------^^^^^
@ -214,7 +167,7 @@ LL | fn f5(ref mut a @ box ref b: Box<NC>) {
LL | *a = Box::new(NC);
| -- mutable borrow later used here
error: aborting due to 24 previous errors
error: aborting due to 17 previous errors
Some errors have detailed explanations: E0007, E0009, E0382, E0502.
For more information about an error, try `rustc --explain E0007`.
Some errors have detailed explanations: E0382, E0502.
For more information about an error, try `rustc --explain E0382`.

View File

@ -0,0 +1,10 @@
// Test that `by_move_binding @ pat_with_by_ref_bindings` is prevented even with promotion.
// Currently this logic exists in HAIR match checking as opposed to borrowck.
#![feature(bindings_after_at)]
#![feature(move_ref_pattern)]
fn main() {
struct U;
let a @ ref b = U; //~ ERROR borrow of moved value
}

View File

@ -0,0 +1,12 @@
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse-promotion.rs:9:9
|
LL | let a @ ref b = U;
| -^^^-----
| | |
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `main::U` which does implement the `Copy` trait
error: aborting due to previous error

View File

@ -0,0 +1,98 @@
// Test that `by_move_binding @ pat_with_by_ref_bindings` is prevented.
#![feature(bindings_after_at)]
#![feature(move_ref_pattern)]
fn main() {
struct U;
// Prevent promotion.
fn u() -> U {
U
}
fn f1(a @ ref b: U) {}
//~^ ERROR borrow of moved value
//~| ERROR borrow of moved value
fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
//~^ 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
fn f3(a @ [ref mut b, ref c]: [U; 2]) {}
//~^ ERROR borrow of moved value
//~| ERROR borrow of moved value
let a @ ref b = U;
//~^ ERROR borrow of moved value
let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
//~^ 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
let a @ [ref mut b, ref c] = [U, U];
//~^ ERROR borrow of moved value
//~| ERROR borrow of moved value
let a @ ref b = u();
//~^ ERROR borrow of moved value
//~| ERROR borrow of moved value
let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
//~^ 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
let a @ [ref mut b, ref c] = [u(), u()];
//~^ ERROR borrow of moved value
//~| ERROR borrow of moved value
match Some(U) {
a @ Some(ref b) => {}
//~^ ERROR borrow of moved value
None => {}
}
match Some((U, U)) {
a @ Some((mut b @ ref mut c, d @ ref e)) => {}
//~^ 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
None => {}
}
match Some([U, U]) {
mut a @ Some([ref b, ref mut c]) => {}
//~^ ERROR borrow of moved value
//~| ERROR borrow of moved value
None => {}
}
match Some(u()) {
a @ Some(ref b) => {}
//~^ ERROR borrow of moved value
//~| ERROR borrow of moved value
None => {}
}
match Some((u(), u())) {
a @ Some((mut b @ ref mut c, d @ ref e)) => {}
//~^ 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
None => {}
}
match Some([u(), u()]) {
mut a @ Some([ref b, ref mut c]) => {}
//~^ ERROR borrow of moved value
//~| ERROR borrow of moved value
None => {}
}
}

View File

@ -0,0 +1,503 @@
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:29:9
|
LL | let a @ ref b = U;
| -^^^-----
| | |
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `main::U` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:9
|
LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
| -^^^^^^^^^^^^---------^^^^^^-----^
| | | |
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:14
|
LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
| -----^^^---------
| | |
| | value borrowed here after move
| value moved into `b` here
| move occurs because `b` has type `main::U` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:33
|
LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
| -^^^-----
| | |
| | value borrowed here after move
| value moved into `d` here
| move occurs because `d` has type `main::U` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:38:9
|
LL | let a @ [ref mut b, ref c] = [U, U];
| -^^^^---------^^-----^
| | | |
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `[main::U; 2]` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:41:9
|
LL | let a @ ref b = u();
| -^^^-----
| | |
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `main::U` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:9
|
LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
| -^^^^^^^^^^^^---------^^^^^^-----^
| | | |
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:14
|
LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
| -----^^^---------
| | |
| | value borrowed here after move
| value moved into `b` here
| move occurs because `b` has type `main::U` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:33
|
LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
| -^^^-----
| | |
| | value borrowed here after move
| value moved into `d` here
| move occurs because `d` has type `main::U` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:51:9
|
LL | let a @ [ref mut b, ref c] = [u(), u()];
| -^^^^---------^^-----^
| | | |
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `[main::U; 2]` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:56:9
|
LL | a @ Some(ref b) => {}
| -^^^^^^^^-----^
| | |
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `std::option::Option<main::U>` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:9
|
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| -^^^^^^^^^^^^^^^^^---------^^^^^^-----^^
| | | |
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `std::option::Option<(main::U, main::U)>` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:19
|
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| -----^^^---------
| | |
| | value borrowed here after move
| value moved into `b` here
| move occurs because `b` has type `main::U` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:38
|
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| -^^^-----
| | |
| | value borrowed here after move
| value moved into `d` here
| move occurs because `d` has type `main::U` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:71:9
|
LL | mut a @ Some([ref b, ref mut c]) => {}
| -----^^^^^^^^^-----^^---------^^
| | | |
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `std::option::Option<[main::U; 2]>` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:77:9
|
LL | a @ Some(ref b) => {}
| -^^^^^^^^-----^
| | |
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `std::option::Option<main::U>` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:9
|
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| -^^^^^^^^^^^^^^^^^---------^^^^^^-----^^
| | | |
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `std::option::Option<(main::U, main::U)>` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:19
|
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| -----^^^---------
| | |
| | value borrowed here after move
| value moved into `b` here
| move occurs because `b` has type `main::U` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:38
|
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| -^^^-----
| | |
| | value borrowed here after move
| value moved into `d` here
| move occurs because `d` has type `main::U` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:93:9
|
LL | mut a @ Some([ref b, ref mut c]) => {}
| -----^^^^^^^^^-----^^---------^^
| | | |
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `std::option::Option<[main::U; 2]>` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:11
|
LL | fn f1(a @ ref b: U) {}
| -^^^-----
| | |
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `main::U` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:11
|
LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
| -----^^^^^^^^-----^^^^^^^^^^-----^
| | | |
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:20
|
LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
| -^^^-----
| | |
| | value borrowed here after move
| value moved into `b` here
| move occurs because `b` has type `main::U` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:31
|
LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
| -----^^^-----
| | |
| | value borrowed here after move
| value moved into `d` here
| move occurs because `d` has type `main::U` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:25:11
|
LL | fn f3(a @ [ref mut b, ref c]: [U; 2]) {}
| -^^^^---------^^-----^
| | | |
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `[main::U; 2]` which does implement the `Copy` trait
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:22
|
LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
| --------^^^^^^^^^
| | |
| | value borrowed here after move
| value moved here
|
= note: move occurs because value has type `main::U`, which does not implement the `Copy` trait
error[E0382]: use of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:33
|
LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
| ------------------------^^^^^^^^^- ------ move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait
| | |
| | value used here after move
| value moved here
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:37
|
LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
| ----^^^^^
| | |
| | value borrowed here after move
| value moved here
|
= note: move occurs because value has type `main::U`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:38:25
|
LL | let a @ [ref mut b, ref c] = [U, U];
| ----------------^^^^^- ------ move occurs because value has type `[main::U; 2]`, which does not implement the `Copy` trait
| | |
| | value borrowed here after move
| value moved here
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:41:13
|
LL | let a @ ref b = u();
| ----^^^^^ --- move occurs because value has type `main::U`, which does not implement the `Copy` trait
| | |
| | value borrowed here after move
| value moved here
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:22
|
LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
| --------^^^^^^^^^
| | |
| | value borrowed here after move
| value moved here
|
= note: move occurs because value has type `main::U`, which does not implement the `Copy` trait
error[E0382]: use of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:33
|
LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
| ------------------------^^^^^^^^^- ---------- move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait
| | |
| | value used here after move
| value moved here
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:37
|
LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
| ----^^^^^
| | |
| | value borrowed here after move
| value moved here
|
= note: move occurs because value has type `main::U`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:51:25
|
LL | let a @ [ref mut b, ref c] = [u(), u()];
| ----------------^^^^^- ---------- move occurs because value has type `[main::U; 2]`, which does not implement the `Copy` trait
| | |
| | value borrowed here after move
| value moved here
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:27
|
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| --------^^^^^^^^^
| | |
| | value borrowed here after move
| value moved here
|
= note: move occurs because value has type `main::U`, which does not implement the `Copy` trait
error[E0382]: use of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:38
|
LL | match Some((U, U)) {
| ------------ move occurs because value has type `std::option::Option<(main::U, main::U)>`, which does not implement the `Copy` trait
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| -----------------------------^^^^^^^^^--
| | |
| | value used here after move
| value moved here
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:42
|
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| ----^^^^^
| | |
| | value borrowed here after move
| value moved here
|
= note: move occurs because value has type `main::U`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:71:30
|
LL | match Some([U, U]) {
| ------------ move occurs because value has type `std::option::Option<[main::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:77:18
|
LL | match Some(u()) {
| --------- move occurs because value has type `std::option::Option<main::U>`, which does not implement the `Copy` trait
LL | a @ Some(ref b) => {}
| ---------^^^^^-
| | |
| | value borrowed here after move
| value moved here
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:27
|
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| --------^^^^^^^^^
| | |
| | value borrowed here after move
| value moved here
|
= note: move occurs because value has type `main::U`, which does not implement the `Copy` trait
error[E0382]: use of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:38
|
LL | match Some((u(), u())) {
| ---------------- move occurs because value has type `std::option::Option<(main::U, main::U)>`, which does not implement the `Copy` trait
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| -----------------------------^^^^^^^^^--
| | |
| | value used here after move
| value moved here
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:42
|
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| ----^^^^^
| | |
| | value borrowed here after move
| value moved here
|
= note: move occurs because value has type `main::U`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:93:30
|
LL | match Some([u(), u()]) {
| ---------------- move occurs because value has type `std::option::Option<[main::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:14:15
|
LL | fn f1(a @ ref b: U) {}
| ----^^^^^
| | |
| | value borrowed here after move
| value moved here
| move occurs because value has type `main::U`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:24
|
LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
| ----^^^^^
| | |
| | value borrowed here after move
| value moved here
|
= note: move occurs because value has type `main::U`, which does not implement the `Copy` trait
error[E0382]: use of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:31
|
LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
| --------------------^^^^^^^^^^^^^-
| | |
| | value used here after move
| value moved here
| move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:39
|
LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
| --------^^^^^
| | |
| | value borrowed here after move
| value moved here
|
= note: move occurs because value has type `main::U`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:25:27
|
LL | fn f3(a @ [ref mut b, ref c]: [U; 2]) {}
| ----------------^^^^^-
| | |
| | value borrowed here after move
| value moved here
| move occurs because value has type `[main::U; 2]`, which does not implement the `Copy` trait
error: aborting due to 48 previous errors
For more information about this error, try `rustc --explain E0382`.

View File

@ -1,9 +1,74 @@
// Test that `ref mut? @ pat_with_by_move_bindings` is prevented.
#![feature(bindings_after_at)]
#![feature(move_ref_pattern)]
fn main() {
match Some("hi".to_string()) {
ref op_string_ref @ Some(s) => {},
//~^ ERROR cannot bind by-move and by-ref in the same pattern [E0009]
None => {},
struct U;
// Prevent promotion.
fn u() -> U {
U
}
fn f1(ref a @ b: U) {}
//~^ ERROR cannot move out of value because it is borrowed
fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
//~^ ERROR cannot move out of value because it is borrowed
//~| ERROR cannot move out of value because it is borrowed
//~| ERROR cannot move out of value because it is borrowed
fn f3(ref mut a @ [b, mut c]: [U; 2]) {}
//~^ ERROR cannot move out of value because it is borrowed
let ref a @ b = U;
//~^ ERROR cannot move out of value because it is borrowed
let ref a @ (ref b @ mut c, ref d @ e) = (U, U);
//~^ ERROR cannot move out of value because it is borrowed
//~| ERROR cannot move out of value because it is borrowed
//~| ERROR cannot move out of value because it is borrowed
let ref mut a @ [b, mut c] = [U, U];
//~^ ERROR cannot move out of value because it is borrowed
let ref a @ b = u();
//~^ ERROR cannot move out of value because it is borrowed
let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
//~^ ERROR cannot move out of value because it is borrowed
//~| ERROR cannot move out of value because it is borrowed
//~| ERROR cannot move out of value because it is borrowed
let ref mut a @ [b, mut c] = [u(), u()];
//~^ ERROR cannot move out of value because it is borrowed
match Some(U) {
ref a @ Some(b) => {}
//~^ ERROR cannot move out of value because it is borrowed
None => {}
}
match Some((U, U)) {
ref a @ Some((ref b @ mut c, ref d @ e)) => {}
//~^ ERROR cannot move out of value because it is borrowed
//~| ERROR cannot move out of value because it is borrowed
//~| ERROR cannot move out of value because it is borrowed
None => {}
}
match Some([U, U]) {
ref mut a @ Some([b, mut c]) => {}
//~^ ERROR cannot move out of value because it is borrowed
None => {}
}
match Some(u()) {
ref a @ Some(b) => {}
//~^ ERROR cannot move out of value because it is borrowed
None => {}
}
match Some((u(), u())) {
ref a @ Some((ref b @ mut c, ref d @ e)) => {}
//~^ ERROR cannot move out of value because it is borrowed
//~| ERROR cannot move out of value because it is borrowed
//~| ERROR cannot move out of value because it is borrowed
None => {}
}
match Some([u(), u()]) {
ref mut a @ Some([b, mut c]) => {}
//~^ ERROR cannot move out of value because it is borrowed
None => {}
}
}

View File

@ -1,12 +1,237 @@
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/borrowck-pat-by-move-and-ref.rs:5:34
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:23:9
|
LL | ref op_string_ref @ Some(s) => {},
| -------------------------^-
| | |
| | by-move pattern here
| by-ref pattern here
LL | let ref a @ b = U;
| -----^^^-
| | |
| | value moved into `b` here
| value borrowed, by `a`, here
error: aborting due to previous error
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:25:9
|
LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U);
| -----^^^^^^^^^^^^-----^^^^^^^^^^-^
| | | |
| | | value moved into `e` here
| | value moved into `c` here
| value borrowed, by `a`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:25:18
|
LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U);
| -----^^^-----
| | |
| | value moved into `c` here
| value borrowed, by `b`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:25:33
|
LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U);
| -----^^^-
| | |
| | value moved into `e` here
| value borrowed, by `d`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:29:9
|
LL | let ref mut a @ [b, mut c] = [U, U];
| ---------^^^^-^^-----^
| | | |
| | | value moved into `c` here
| | value moved into `b` here
| value borrowed, by `a`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:31:9
|
LL | let ref a @ b = u();
| -----^^^-
| | |
| | value moved into `b` here
| value borrowed, by `a`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:33:9
|
LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
| -----^^^^^^^^^^^^-----^^^^^^^^^^-^
| | | |
| | | value moved into `e` here
| | value moved into `c` here
| value borrowed, by `a`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:33:18
|
LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
| -----^^^-----
| | |
| | value moved into `c` here
| value borrowed, by `b`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:33:33
|
LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
| -----^^^-
| | |
| | value moved into `e` here
| value borrowed, by `d`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:37:9
|
LL | let ref mut a @ [b, mut c] = [u(), u()];
| ---------^^^^-^^-----^
| | | |
| | | value moved into `c` here
| | value moved into `b` here
| value borrowed, by `a`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:41:9
|
LL | ref a @ Some(b) => {}
| -----^^^^^^^^-^
| | |
| | value moved into `b` here
| value borrowed, by `a`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:46:9
|
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| -----^^^^^^^^^^^^^^^^^-----^^^^^^^^^^-^^
| | | |
| | | value moved into `e` here
| | value moved into `c` here
| value borrowed, by `a`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:46:23
|
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| -----^^^-----
| | |
| | value moved into `c` here
| value borrowed, by `b`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:46:38
|
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| -----^^^-
| | |
| | value moved into `e` here
| value borrowed, by `d`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:53:9
|
LL | ref mut a @ Some([b, mut c]) => {}
| ---------^^^^^^^^^-^^-----^^
| | | |
| | | value moved into `c` here
| | value moved into `b` here
| value borrowed, by `a`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:58:9
|
LL | ref a @ Some(b) => {}
| -----^^^^^^^^-^
| | |
| | value moved into `b` here
| value borrowed, by `a`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:63:9
|
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| -----^^^^^^^^^^^^^^^^^-----^^^^^^^^^^-^^
| | | |
| | | value moved into `e` here
| | value moved into `c` here
| value borrowed, by `a`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:63:23
|
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| -----^^^-----
| | |
| | value moved into `c` here
| value borrowed, by `b`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:63:38
|
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| -----^^^-
| | |
| | value moved into `e` here
| value borrowed, by `d`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:70:9
|
LL | ref mut a @ Some([b, mut c]) => {}
| ---------^^^^^^^^^-^^-----^^
| | | |
| | | value moved into `c` here
| | value moved into `b` here
| value borrowed, by `a`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:14:11
|
LL | fn f1(ref a @ b: U) {}
| -----^^^-
| | |
| | value moved into `b` here
| value borrowed, by `a`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:16:11
|
LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
| -----^^^^^^^^^^^^-----^^^^^^^^^^-^
| | | |
| | | value moved into `e` here
| | value moved into `c` here
| value borrowed, by `a`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:16:20
|
LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
| -----^^^-----
| | |
| | value moved into `c` here
| value borrowed, by `b`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:16:35
|
LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
| -----^^^-
| | |
| | value moved into `e` here
| value borrowed, by `d`, here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:20:11
|
LL | fn f3(ref mut a @ [b, mut c]: [U; 2]) {}
| ---------^^^^-^^-----^
| | | |
| | | value moved into `c` here
| | value moved into `b` here
| value borrowed, by `a`, here
error: aborting due to 25 previous errors
For more information about this error, try `rustc --explain E0009`.

View File

@ -1,4 +1,5 @@
#![feature(bindings_after_at)]
#![feature(move_ref_pattern)]
enum Option<T> {
None,
@ -8,7 +9,7 @@ enum Option<T> {
fn main() {
match &mut Some(1) {
ref mut z @ &mut Some(ref a) => {
//~^ ERROR cannot borrow `z` 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 `_` as immutable because it is also borrowed as mutable
**z = None;
println!("{}", *a);
@ -22,49 +23,52 @@ fn main() {
fn u() -> U { U }
fn f1(ref a @ ref mut b: U) {}
//~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable
//~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
fn f2(ref mut a @ ref b: U) {}
//~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable
//~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable
fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {}
//~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable
//~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
fn f4_also_moved(ref a @ ref mut b @ c: U) {}
//~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
//~| ERROR cannot move out of value because it is borrowed
let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub
//~^ ERROR cannot borrow `a` as mutable more than once at a time
//~| ERROR cannot borrow `b` as mutable because it is also borrowed as immutable
//~^ ERROR cannot borrow value as mutable more than once at a time
//~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
let ref a @ ref mut b = U;
//~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable
//~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
let ref mut a @ ref b = U;
//~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable
//~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable
let ref a @ (ref mut b, ref mut c) = (U, U);
//~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable
//~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
let ref mut a @ (ref b, ref c) = (U, U);
//~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable
//~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable
let ref mut a @ ref b = u();
//~^ ERROR cannot borrow `a` 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 `_` as immutable because it is also borrowed as mutable
*a = u();
drop(b);
let ref a @ ref mut b = u();
//~^ ERROR cannot borrow `a` 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 `_` as mutable because it is also borrowed as immutable
*b = u();
drop(a);
let ref mut a @ ref b = U;
//~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable
//~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable
*a = U;
drop(b);
let ref a @ ref mut b = U;
//~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable
//~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
*b = U;
drop(a);
match Ok(U) {
ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => {
//~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable
//~| ERROR cannot borrow `a` 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
*a = Err(U);
drop(b);
}
@ -72,8 +76,8 @@ fn main() {
match Ok(U) {
ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
//~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable
//~| ERROR cannot borrow `a` 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 `_` as mutable because it is also borrowed as immutable
//~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable
*b = U;
@ -83,52 +87,52 @@ fn main() {
match Ok(U) {
ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
//~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable
//~| ERROR cannot borrow `a` 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 assign to `*b`, as it is immutable for the pattern guard
_ => {}
}
match Ok(U) {
ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
//~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable
//~| ERROR cannot borrow `a` 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 assign to `*a`, as it is immutable for the pattern guard
_ => {}
}
match Ok(U) {
ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
//~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable
//~| ERROR cannot borrow `a` 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 move out of `b` in pattern guard
//~| ERROR cannot move out of `b` in pattern guard
_ => {}
}
match Ok(U) {
ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
//~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable
//~| ERROR cannot borrow `a` 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 move out of `a` in pattern guard
//~| ERROR cannot move out of `a` in pattern guard
_ => {}
}
let ref a @ (ref mut b, ref mut c) = (U, U);
//~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable
//~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
*b = U;
*c = U;
let ref a @ (ref mut b, ref mut c) = (U, U);
//~^ ERROR cannot borrow `a` 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 `_` as mutable because it is also borrowed as immutable
//~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable
*b = U;
drop(a);
let ref a @ (ref mut b, ref mut c) = (U, U);
//~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable
//~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
*b = U; //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable
*c = U; //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable
drop(a);
let ref mut a @ (ref b, ref c) = (U, U);
//~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable
//~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable
}

View File

@ -1,282 +1,301 @@
error: cannot borrow `z` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:10:9
error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:9
|
LL | ref mut z @ &mut Some(ref a) => {
| ---------^^^^^^^^^^^^^-----^
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| | immutable borrow, by `a`, occurs here
| mutable borrow, by `z`, occurs here
error: cannot borrow `a` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:9
error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:9
|
LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub
| ---------^^^^-----------------^
| | | |
| | | another mutable borrow occurs here
| | also borrowed as immutable here
| first mutable borrow occurs here
| | | another mutable borrow, by `c`, occurs here
| | also borrowed as immutable, by `b`, here
| first mutable borrow, by `a`, occurs here
error: cannot borrow `b` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:22
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:22
|
LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub
| -----^^^---------
| | |
| | mutable borrow occurs here
| immutable borrow occurs here
| | mutable borrow, by `c`, occurs here
| immutable borrow, by `b`, occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:9
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:39:9
|
LL | let ref a @ ref mut b = U;
| -----^^^---------
| | |
| | mutable borrow occurs here
| immutable borrow occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:37:9
error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:41:9
|
LL | let ref mut a @ ref b = U;
| ---------^^^-----
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| | immutable borrow, by `b`, occurs here
| mutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:39:9
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:43:9
|
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| -----^^^^---------^^---------^
| | | |
| | | mutable borrow occurs here
| | mutable borrow occurs here
| immutable borrow occurs here
| | | mutable borrow, by `c`, occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:41:9
error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:45:9
|
LL | let ref mut a @ (ref b, ref c) = (U, U);
| ---------^^^^-----^^-----^
| | | |
| | | immutable borrow occurs here
| | immutable borrow occurs here
| mutable borrow occurs here
| | | immutable borrow, by `c`, occurs here
| | immutable borrow, by `b`, occurs here
| mutable borrow, by `a`, occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:44:9
error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:48:9
|
LL | let ref mut a @ ref b = u();
| ---------^^^-----
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| | immutable borrow, by `b`, occurs here
| mutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:49:9
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:53:9
|
LL | let ref a @ ref mut b = u();
| -----^^^---------
| | |
| | mutable borrow occurs here
| immutable borrow occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:55:9
error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:59:9
|
LL | let ref mut a @ ref b = U;
| ---------^^^-----
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| | immutable borrow, by `b`, occurs here
| mutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:59:9
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:63:9
|
LL | let ref a @ ref mut b = U;
| -----^^^---------
| | |
| | mutable borrow occurs here
| immutable borrow occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:65:9
error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:69:9
|
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => {
| ---------^^^^^^-----^
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| | immutable borrow, by `b`, occurs here
| mutable borrow, by `a`, occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:65:33
error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:69:33
|
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => {
| ---------^^^^^^^-----^
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| | immutable borrow, by `b`, occurs here
| mutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:9
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:9
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
| -----^^^^^^---------^
| | |
| | mutable borrow occurs here
| immutable borrow occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:33
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:33
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
| -----^^^^^^^---------^
| | |
| | mutable borrow occurs here
| immutable borrow occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:9
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:89:9
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
| -----^^^^^^---------^
| | |
| | mutable borrow occurs here
| immutable borrow occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:33
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:89:33
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
| -----^^^^^^^---------^
| | |
| | mutable borrow occurs here
| immutable borrow occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:9
error: cannot borrow value as immutable because it is also borrowed as mutable
--> $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 } => {}
| ---------^^^^^^-----^
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| | immutable borrow, by `b`, occurs here
| mutable borrow, by `a`, occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:33
error: cannot borrow value as immutable because it is also borrowed as mutable
--> $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 } => {}
| ---------^^^^^^^-----^
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| | immutable borrow, by `b`, occurs here
| mutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:9
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $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
| immutable borrow occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:33
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $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 occurs here
| immutable borrow occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:9
error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:111:9
|
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
| ---------^^^^^^-----^
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| | immutable borrow, by `b`, occurs here
| mutable borrow, by `a`, occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:33
error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:111:33
|
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
| ---------^^^^^^^-----^
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| | immutable borrow, by `b`, occurs here
| mutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:115:9
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:119:9
|
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| -----^^^^---------^^---------^
| | | |
| | | mutable borrow occurs here
| | mutable borrow occurs here
| immutable borrow occurs here
| | | mutable borrow, by `c`, occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:9
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:124:9
|
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| -----^^^^---------^^---------^
| | | |
| | | mutable borrow occurs here
| | mutable borrow occurs here
| immutable borrow occurs here
| | | mutable borrow, by `c`, occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:9
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:131:9
|
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| -----^^^^---------^^---------^
| | | |
| | | mutable borrow occurs here
| | mutable borrow occurs here
| immutable borrow occurs here
| | | mutable borrow, by `c`, occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:132:9
error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:136:9
|
LL | let ref mut a @ (ref b, ref c) = (U, U);
| ---------^^^^-----^^-----^
| | | |
| | | immutable borrow occurs here
| | immutable borrow occurs here
| mutable borrow occurs here
| | | immutable borrow, by `c`, occurs here
| | immutable borrow, by `b`, occurs here
| mutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:24:11
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:25:11
|
LL | fn f1(ref a @ ref mut b: U) {}
| -----^^^---------
| | |
| | mutable borrow occurs here
| immutable borrow occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:26:11
error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:27:11
|
LL | fn f2(ref mut a @ ref b: U) {}
| ---------^^^-----
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| | immutable borrow, by `b`, occurs here
| mutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:11
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:29:11
|
LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {}
| -----^^^^^^^^^^^----------------^^^^^^^^
| | |
| | mutable borrow occurs here
| immutable borrow occurs here
| | mutable borrow, by `mid`, occurs here
| immutable borrow, by `a`, occurs here
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:22
|
LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {}
| -----^^^-------------
| | | |
| | | also moved into `c` here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:30
|
LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {}
| ---------^^^-
| | |
| | value moved into `c` here
| value borrowed, by `b`, here
error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:10:31
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:31
|
LL | ref mut z @ &mut Some(ref a) => {
| ----------------------^^^^^-
@ -288,7 +307,7 @@ LL | **z = None;
| ---------- mutable borrow later used here
error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:44:21
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:48:21
|
LL | let ref mut a @ ref b = u();
| ------------^^^^^
@ -300,7 +319,7 @@ LL | *a = u();
| -------- mutable borrow later used here
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:49:17
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:53:17
|
LL | let ref a @ ref mut b = u();
| --------^^^^^^^^^
@ -312,7 +331,7 @@ LL | drop(a);
| - immutable borrow later used here
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:20
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:20
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
| -----------^^^^^^^^^-
@ -324,7 +343,7 @@ LL | drop(a);
| - immutable borrow later used here
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:45
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:45
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
| ------------^^^^^^^^^-
@ -336,7 +355,7 @@ LL | drop(a);
| - immutable borrow later used here
error[E0594]: cannot assign to `*b`, as it is immutable for the pattern guard
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:61
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:89:61
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
| ^^^^^^ cannot assign
@ -344,7 +363,7 @@ 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
error[E0594]: cannot assign to `*a`, as it is immutable for the pattern guard
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:92: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 } => {}
| ^^^^^^^^^^^ cannot assign
@ -352,7 +371,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa
= note: variables bound in patterns are immutable until the end of the pattern guard
error[E0507]: cannot move out of `b` in pattern guard
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:99: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 } => {}
| ^ move occurs because `b` has type `&mut main::U`, which does not implement the `Copy` trait
@ -360,7 +379,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
error[E0507]: cannot move out of `b` in pattern guard
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:99: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 } => {}
| ^ move occurs because `b` has type `&mut main::U`, which does not implement the `Copy` trait
@ -368,7 +387,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
error[E0507]: cannot move out of `a` in pattern guard
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:66
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:111:66
|
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
| ^ move occurs because `a` has type `&mut std::result::Result<main::U, main::U>`, which does not implement the `Copy` trait
@ -376,7 +395,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
error[E0507]: cannot move out of `a` in pattern guard
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:66
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:111:66
|
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
| ^ move occurs because `a` has type `&mut std::result::Result<main::U, main::U>`, which does not implement the `Copy` trait
@ -384,7 +403,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
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:18
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:124:18
|
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| ---------^^^^^^^^^------------
@ -396,7 +415,7 @@ LL | drop(a);
| - immutable borrow later used here
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:29
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:124:29
|
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| --------------------^^^^^^^^^-
@ -408,7 +427,7 @@ LL | drop(a);
| - immutable borrow later used here
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:18
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:131:18
|
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| ---------^^^^^^^^^------------
@ -420,7 +439,7 @@ LL | drop(a);
| - immutable borrow later used here
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:29
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:131:29
|
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| --------------------^^^^^^^^^-
@ -431,7 +450,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U);
LL | drop(a);
| - immutable borrow later used here
error: aborting due to 45 previous errors
error: aborting due to 47 previous errors
Some errors have detailed explanations: E0502, E0507, E0594.
For more information about an error, try `rustc --explain E0502`.

View File

@ -1,6 +1,7 @@
// Test that `ref mut x @ ref mut y` and varieties of that are not allowed.
#![feature(bindings_after_at)]
#![feature(move_ref_pattern)]
fn main() {
struct U;
@ -8,39 +9,42 @@ fn main() {
fn u() -> U { U }
fn f1(ref mut a @ ref mut b: U) {}
//~^ ERROR cannot borrow `a` as mutable more than once at a time
//~^ ERROR cannot borrow value as mutable more than once at a time
fn f2(ref mut a @ ref mut b: U) {}
//~^ ERROR cannot borrow `a` as mutable more than once at a time
//~^ ERROR cannot borrow value as mutable more than once at a time
fn f3(
ref mut a @ [
//~^ ERROR cannot borrow `a` as mutable more than once at a time
//~^ ERROR cannot borrow value as mutable more than once at a time
[ref b @ .., _],
[_, ref mut mid @ ..],
..,
[..],
] : [[U; 4]; 5]
) {}
fn f4_also_moved(ref mut a @ ref mut b @ c: U) {}
//~^ ERROR cannot borrow value as mutable more than once at a time
//~| ERROR cannot move out of value because it is borrowed
let ref mut a @ ref mut b = U;
//~^ ERROR cannot borrow `a` as mutable more than once at a time
//~^ ERROR cannot borrow value as mutable more than once at a time
//~| ERROR cannot borrow `_` as mutable more than once at a time
drop(a);
let ref mut a @ ref mut b = U;
//~^ ERROR cannot borrow `a` as mutable more than once at a time
//~^ ERROR cannot borrow value as mutable more than once at a time
drop(b);
let ref mut a @ ref mut b = U;
//~^ ERROR cannot borrow `a` as mutable more than once at a time
//~^ ERROR cannot borrow value as mutable more than once at a time
let ref mut a @ ref mut b = U;
//~^ ERROR cannot borrow `a` as mutable more than once at a time
//~^ ERROR cannot borrow value as mutable more than once at a time
//~| ERROR cannot borrow `_` as mutable more than once at a time
*a = U;
let ref mut a @ ref mut b = U;
//~^ ERROR cannot borrow `a` as mutable more than once at a time
//~^ ERROR cannot borrow value as mutable more than once at a time
*b = U;
let ref mut a @ (
//~^ ERROR cannot borrow `a` as mutable more than once at a time
//~^ ERROR cannot borrow value as mutable more than once at a time
ref mut b,
[
ref mut c,
@ -50,7 +54,7 @@ fn main() {
) = (U, [U, U, U]);
let ref mut a @ (
//~^ ERROR cannot borrow `a` as mutable more than once at a time
//~^ ERROR cannot borrow value as mutable more than once at a time
ref mut b,
[
ref mut c,
@ -60,37 +64,37 @@ fn main() {
) = (u(), [u(), u(), u()]);
let a @ (ref mut b, ref mut c) = (U, U);
//~^ ERROR cannot bind by-move with sub-bindings
//~^ ERROR borrow of moved value
//~| ERROR borrow of moved value
let mut val = (U, [U, U]);
let a @ (b, [c, d]) = &mut val; // Same as ^--
//~^ ERROR cannot bind by-move with sub-bindings
//~^ ERROR borrow of moved value
//~| ERROR borrow of moved value
let a @ &mut ref mut b = &mut U;
//~^ ERROR cannot bind by-move with sub-bindings
//~^ ERROR borrow of moved value
//~| ERROR borrow of moved value
let a @ &mut (ref mut b, ref mut c) = &mut (U, U);
//~^ ERROR cannot bind by-move with sub-bindings
//~^ ERROR borrow of moved value
//~| ERROR borrow of moved value
match Ok(U) {
ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
//~^ ERROR cannot borrow `a` as mutable more than once at a time
//~| ERROR cannot borrow `a` 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
}
}
match Ok(U) {
ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
//~^ ERROR cannot borrow `a` as mutable more than once at a time
//~| ERROR cannot borrow `a` 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;
}
}
match Ok(U) {
ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
//~^ ERROR cannot borrow `a` as mutable more than once at a time
//~| ERROR cannot borrow `a` 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 `_` as mutable more than once at a time
//~| ERROR cannot borrow `_` as mutable more than once at a time
*a = Err(U);
@ -101,8 +105,8 @@ fn main() {
}
match Ok(U) {
ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
//~^ ERROR cannot borrow `a` as mutable more than once at a time
//~| ERROR cannot borrow `a` 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 `_` as mutable more than once at a time
//~| ERROR cannot borrow `_` as mutable more than once at a time
drop(a);

View File

@ -1,226 +1,265 @@
error: cannot borrow `a` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:24:9
|
LL | let ref mut a @ ref mut b = U;
| ---------^^^---------
| | |
| | another mutable borrow occurs here
| first mutable borrow occurs here
error: cannot borrow `a` 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:28:9
|
LL | let ref mut a @ ref mut b = U;
| ---------^^^---------
| | |
| | another mutable borrow occurs here
| first mutable borrow occurs here
| | another mutable borrow, by `b`, occurs here
| first mutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:31:9
error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:32:9
|
LL | let ref mut a @ ref mut b = U;
| ---------^^^---------
| | |
| | another mutable borrow occurs here
| first mutable borrow occurs here
| | another mutable borrow, by `b`, occurs here
| first mutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:34:9
error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:35:9
|
LL | let ref mut a @ ref mut b = U;
| ---------^^^---------
| | |
| | another mutable borrow occurs here
| first mutable borrow occurs here
| | another mutable borrow, by `b`, occurs here
| first mutable borrow, by `a`, occurs here
error: cannot borrow `a` 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:38:9
|
LL | let ref mut a @ ref mut b = U;
| ---------^^^---------
| | |
| | another mutable borrow occurs here
| first mutable borrow occurs here
| | another mutable borrow, by `b`, occurs here
| first mutable borrow, by `a`, occurs here
error: cannot borrow `a` 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:42:9
|
LL | let ref mut a @ ref mut b = U;
| ---------^^^---------
| | |
| | another mutable borrow, by `b`, occurs here
| first mutable borrow, by `a`, occurs here
error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:46:9
|
LL | let ref mut a @ (
| ^--------
| |
| _________first mutable borrow occurs here
| _________first mutable borrow, by `a`, occurs here
| |
LL | |
LL | | ref mut b,
| | --------- another mutable borrow occurs here
| | --------- another mutable borrow, by `b`, occurs here
LL | | [
LL | | ref mut c,
| | --------- another mutable borrow occurs here
| | --------- another mutable borrow, by `c`, occurs here
LL | | ref mut d,
| | --------- another mutable borrow occurs here
| | --------- another mutable borrow, by `d`, occurs here
LL | | ref e,
| | ----- also borrowed as immutable here
| | ----- also borrowed as immutable, by `e`, here
LL | | ]
LL | | ) = (U, [U, U, U]);
| |_____^
error: cannot borrow `a` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:52:9
error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:56:9
|
LL | let ref mut a @ (
| ^--------
| |
| _________first mutable borrow occurs here
| _________first mutable borrow, by `a`, occurs here
| |
LL | |
LL | | ref mut b,
| | --------- another mutable borrow occurs here
| | --------- another mutable borrow, by `b`, occurs here
LL | | [
LL | | ref mut c,
| | --------- another mutable borrow occurs here
| | --------- another mutable borrow, by `c`, occurs here
LL | | ref mut d,
| | --------- another mutable borrow occurs here
| | --------- another mutable borrow, by `d`, occurs here
LL | | ref e,
| | ----- also borrowed as immutable here
| | ----- also borrowed as immutable, by `e`, here
LL | | ]
LL | | ) = (u(), [u(), u(), u()]);
| |_________^
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/borrowck-pat-ref-mut-twice.rs:62:9
|
LL | let a @ (ref mut b, ref mut c) = (U, U);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
error: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-twice.rs:66:9
|
LL | let a @ (b, [c, d]) = &mut val; // Same as ^--
| ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
LL | let a @ (ref mut b, ref mut c) = (U, U);
| -^^^^---------^^---------^
| | | |
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait
error[E0007]: cannot bind by-move with sub-bindings
error: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-twice.rs:70:9
|
LL | let a @ &mut ref mut b = &mut U;
| ^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
LL | let a @ (b, [c, d]) = &mut val; // Same as ^--
| -^^^^-^^^-^^-^^
| | | | |
| | | | value borrowed here after move
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `&mut (main::U, [main::U; 2])` which does implement the `Copy` trait
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/borrowck-pat-ref-mut-twice.rs:73:9
error: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-twice.rs:74:9
|
LL | let a @ &mut ref mut b = &mut U;
| -^^^^^^^^---------
| | |
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `&mut main::U` which does implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-twice.rs:77:9
|
LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
| -^^^^^^^^^---------^^---------^
| | | |
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `&mut (main::U, main::U)` which does implement the `Copy` trait
error: cannot borrow `a` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:78:9
error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:82:9
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^---------^
| | |
| | another mutable borrow occurs here
| first mutable borrow occurs here
| | another mutable borrow, by `b`, occurs here
| first mutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:78:37
error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:82:37
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^^---------^
| | |
| | another mutable borrow occurs here
| first mutable borrow occurs here
| | another mutable borrow, by `b`, occurs here
| first mutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:84:9
error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:88:9
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^---------^
| | |
| | another mutable borrow occurs here
| first mutable borrow occurs here
| | another mutable borrow, by `b`, occurs here
| first mutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:84:37
error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:88:37
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^^---------^
| | |
| | another mutable borrow occurs here
| first mutable borrow occurs here
| | another mutable borrow, by `b`, occurs here
| first mutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:91:9
error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:95:9
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^---------^
| | |
| | another mutable borrow occurs here
| first mutable borrow occurs here
| | another mutable borrow, by `b`, occurs here
| first mutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:91:37
error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:95:37
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^^---------^
| | |
| | another mutable borrow occurs here
| first mutable borrow occurs here
| | another mutable borrow, by `b`, occurs here
| first mutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:103:9
error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:107:9
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^---------^
| | |
| | another mutable borrow occurs here
| first mutable borrow occurs here
| | another mutable borrow, by `b`, occurs here
| first mutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:103:37
error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:107:37
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^^---------^
| | |
| | another mutable borrow occurs here
| first mutable borrow occurs here
| | another mutable borrow, by `b`, occurs here
| first mutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:10:11
error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:11:11
|
LL | fn f1(ref mut a @ ref mut b: U) {}
| ---------^^^---------
| | |
| | another mutable borrow occurs here
| first mutable borrow occurs here
| | another mutable borrow, by `b`, occurs here
| first mutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:12:11
error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:13:11
|
LL | fn f2(ref mut a @ ref mut b: U) {}
| ---------^^^---------
| | |
| | another mutable borrow occurs here
| first mutable borrow occurs here
| | another mutable borrow, by `b`, occurs here
| first mutable borrow, by `a`, occurs here
error: cannot borrow `a` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:15:9
error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:16:9
|
LL | ref mut a @ [
| ^--------
| |
| _________first mutable borrow occurs here
| _________first mutable borrow, by `a`, occurs here
| |
LL | |
LL | | [ref b @ .., _],
| | ---------- also borrowed as immutable here
| | ---------- also borrowed as immutable, by `b`, here
LL | | [_, ref mut mid @ ..],
| | ---------------- another mutable borrow occurs here
| | ---------------- another mutable borrow, by `mid`, occurs here
LL | | ..,
LL | | [..],
LL | | ] : [[U; 4]; 5]
| |_________^
error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:24:22
|
LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {}
| ---------^^^-------------
| | | |
| | | also moved into `c` here
| | another mutable borrow, by `b`, occurs here
| first mutable borrow, by `a`, occurs here
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-ref-mut-twice.rs:24:34
|
LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {}
| ---------^^^-
| | |
| | value moved into `c` here
| value borrowed, by `b`, here
error[E0499]: cannot borrow `_` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:24:21
--> $DIR/borrowck-pat-ref-mut-twice.rs:28:21
|
LL | let ref mut a @ ref mut b = U;
| ------------^^^^^^^^^
@ -232,7 +271,7 @@ LL | drop(a);
| - first borrow later used here
error[E0499]: cannot borrow `_` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:34:21
--> $DIR/borrowck-pat-ref-mut-twice.rs:38:21
|
LL | let ref mut a @ ref mut b = U;
| ------------^^^^^^^^^
@ -244,7 +283,7 @@ LL | *a = U;
| ------ first borrow later used here
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-twice.rs:62:25
--> $DIR/borrowck-pat-ref-mut-twice.rs:66:25
|
LL | let a @ (ref mut b, ref mut c) = (U, U);
| ----------------^^^^^^^^^- ------ move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait
@ -253,7 +292,7 @@ LL | let a @ (ref mut b, ref mut c) = (U, U);
| value moved here
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-twice.rs:66:21
--> $DIR/borrowck-pat-ref-mut-twice.rs:70:21
|
LL | let a @ (b, [c, d]) = &mut val; // Same as ^--
| ------------^-- -------- move occurs because value has type `&mut (main::U, [main::U; 2])`, which does not implement the `Copy` trait
@ -262,7 +301,7 @@ LL | let a @ (b, [c, d]) = &mut val; // Same as ^--
| value moved here
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-twice.rs:70:18
--> $DIR/borrowck-pat-ref-mut-twice.rs:74:18
|
LL | let a @ &mut ref mut b = &mut U;
| ---------^^^^^^^^^ ------ move occurs because value has type `&mut main::U`, which does not implement the `Copy` trait
@ -271,7 +310,7 @@ LL | let a @ &mut ref mut b = &mut U;
| value moved here
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-twice.rs:73:30
--> $DIR/borrowck-pat-ref-mut-twice.rs:77:30
|
LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U);
| ---------------------^^^^^^^^^- ----------- move occurs because value has type `&mut (main::U, main::U)`, which does not implement the `Copy` trait
@ -280,7 +319,7 @@ LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U);
| value moved here
error[E0499]: cannot borrow `_` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:91:24
--> $DIR/borrowck-pat-ref-mut-twice.rs:95:24
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------------^^^^^^^^^-
@ -292,7 +331,7 @@ LL | *a = Err(U);
| ----------- first borrow later used here
error[E0499]: cannot borrow `_` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:91:53
--> $DIR/borrowck-pat-ref-mut-twice.rs:95:53
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ----------------^^^^^^^^^-
@ -304,7 +343,7 @@ LL | *a = Err(U);
| ----------- first borrow later used here
error[E0499]: cannot borrow `_` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:103:24
--> $DIR/borrowck-pat-ref-mut-twice.rs:107:24
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------------^^^^^^^^^-
@ -316,7 +355,7 @@ LL | drop(a);
| - first borrow later used here
error[E0499]: cannot borrow `_` as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:103:53
--> $DIR/borrowck-pat-ref-mut-twice.rs:107:53
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ----------------^^^^^^^^^-
@ -327,7 +366,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
LL | drop(a);
| - first borrow later used here
error: aborting due to 32 previous errors
error: aborting due to 34 previous errors
Some errors have detailed explanations: E0007, E0382, E0499.
For more information about an error, try `rustc --explain E0007`.
Some errors have detailed explanations: E0382, E0499.
For more information about an error, try `rustc --explain E0382`.

View File

@ -1,6 +1,7 @@
// Test that mixing `Copy` and non-`Copy` types in `@` patterns is forbidden.
#![feature(bindings_after_at)]
#![feature(move_ref_pattern)]
#[derive(Copy, Clone)]
struct C;
@ -9,12 +10,9 @@ struct NC<A, B>(A, B);
fn main() {
let a @ NC(b, c) = NC(C, C);
//~^ ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
//~^ ERROR use of moved value
let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C));
//~^ ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
//~| ERROR cannot bind by-move with sub-bindings
//~^ ERROR use of moved value
//~| ERROR use of moved value
}

View File

@ -1,23 +1,5 @@
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/copy-and-move-mixed.rs:11:9
|
LL | let a @ NC(b, c) = NC(C, C);
| ^^^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/copy-and-move-mixed.rs:15:9
|
LL | let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C));
| ^^^^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/copy-and-move-mixed.rs:15:19
|
LL | let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C));
| ^^^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0382]: use of moved value
--> $DIR/copy-and-move-mixed.rs:11:19
--> $DIR/copy-and-move-mixed.rs:12:19
|
LL | let a @ NC(b, c) = NC(C, C);
| ----------^- -------- move occurs because value has type `NC<C, C>`, which does not implement the `Copy` trait
@ -45,7 +27,6 @@ LL | let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C));
|
= note: move occurs because value has type `NC<C, C>`, which does not implement the `Copy` trait
error: aborting due to 6 previous errors
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0007, E0382.
For more information about an error, try `rustc --explain E0007`.
For more information about this error, try `rustc --explain E0382`.

View File

@ -8,6 +8,7 @@
// this would create problems for the generalization aforementioned.
#![feature(bindings_after_at)]
#![feature(move_ref_pattern)]
fn main() {
struct NotCopy;
@ -24,14 +25,26 @@ fn main() {
let ref a @ b = &NotCopy; // OK
let _: &&NotCopy = a;
let ref a @ b = NotCopy; //~ ERROR cannot bind by-move and by-ref in the same pattern
let ref mut a @ b = NotCopy; //~ ERROR cannot bind by-move and by-ref in the same pattern
let ref a @ b = NotCopy; //~ ERROR cannot move out of value because it is borrowed
let _a: &NotCopy = a;
let _b: NotCopy = b;
let ref mut a @ b = NotCopy; //~ ERROR cannot move out of value because it is borrowed
//~^ ERROR cannot move out of `_` because it is borrowed
let _a: &NotCopy = a;
let _b: NotCopy = b;
match Ok(NotCopy) {
Ok(ref a @ b) | Err(ref a @ b) => {}
//~^ ERROR cannot bind by-move and by-ref in the same pattern
Ok(ref a @ b) | Err(b @ ref a) => {
//~^ ERROR cannot move out of value because it is borrowed
//~| ERROR borrow of moved value
let _a: &NotCopy = a;
let _b: NotCopy = b;
}
}
match NotCopy {
ref a @ b => {}
//~^ ERROR cannot bind by-move and by-ref in the same pattern
ref a @ b => {
//~^ ERROR cannot move out of value because it is borrowed
let _a: &NotCopy = a;
let _b: NotCopy = b;
}
}
}

View File

@ -1,41 +1,61 @@
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/default-binding-modes-both-sides-independent.rs:27:17
error: cannot move out of value because it is borrowed
--> $DIR/default-binding-modes-both-sides-independent.rs:28:9
|
LL | let ref a @ b = NotCopy;
| --------^
| -----^^^-
| | |
| | by-move pattern here
| by-ref pattern here
| | value moved into `b` here
| value borrowed, by `a`, here
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/default-binding-modes-both-sides-independent.rs:28:21
error: cannot move out of value because it is borrowed
--> $DIR/default-binding-modes-both-sides-independent.rs:31:9
|
LL | let ref mut a @ b = NotCopy;
| ---------^^^-
| | |
| | value moved into `b` here
| value borrowed, by `a`, here
error: cannot move out of value because it is borrowed
--> $DIR/default-binding-modes-both-sides-independent.rs:36:12
|
LL | Ok(ref a @ b) | Err(b @ ref a) => {
| -----^^^-
| | |
| | value moved into `b` here
| value borrowed, by `a`, here
error: borrow of moved value
--> $DIR/default-binding-modes-both-sides-independent.rs:36:29
|
LL | Ok(ref a @ b) | Err(b @ ref a) => {
| -^^^-----
| | |
| | value borrowed here after move
| value moved into `b` here
| move occurs because `b` has type `main::NotCopy` which does implement the `Copy` trait
error: cannot move out of value because it is borrowed
--> $DIR/default-binding-modes-both-sides-independent.rs:44:9
|
LL | ref a @ b => {
| -----^^^-
| | |
| | value moved into `b` here
| value borrowed, by `a`, here
error[E0505]: cannot move out of `_` because it is borrowed
--> $DIR/default-binding-modes-both-sides-independent.rs:31:21
|
LL | let ref mut a @ b = NotCopy;
| ------------^
| | |
| | by-move pattern here
| by-ref pattern here
| | move out of value occurs here
| borrow of value occurs here
LL |
LL | let _a: &NotCopy = a;
| - borrow later used here
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/default-binding-modes-both-sides-independent.rs:30:20
|
LL | Ok(ref a @ b) | Err(ref a @ b) => {}
| --------^ --------^
| | | | |
| | | | by-move pattern here
| | | by-ref pattern here
| | by-move pattern here
| by-ref pattern here
error: aborting due to 6 previous errors
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/default-binding-modes-both-sides-independent.rs:34:17
|
LL | ref a @ b => {}
| --------^
| | |
| | by-move pattern here
| by-ref pattern here
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0009`.
For more information about this error, try `rustc --explain E0505`.

View File

@ -0,0 +1,31 @@
// check-pass
#![feature(move_ref_pattern)]
fn main() {}
struct U;
fn slice() {
let mut arr = [U, U, U, U, U, U, U, U];
let [ref _x0, _x1, _, mut _x3, .., ref _x6, _x7] = arr;
_x3 = U;
let [ref mut _x0, _, ref _x2, _, _x4, ref mut _x5, _x6, _] = arr;
*_x5 = U;
let [_, _, _x2, _, _, _x5, _, _] = arr;
*_x0 = U;
let [ref _x0, ..] = arr;
let [_x0, ..] = arr;
}
fn tuple() {
let mut tup = (U, U, U, U, U);
let (ref _x0, mut _x1, ref _x2, ..) = tup;
_x1 = U;
let (ref mut _x0, _, _, ref _x3, _x4) = tup;
let (_, _, _, _x3, _) = tup;
*_x0 = U;
drop(_x2);
drop(tup.2);
let (_x0, _, _, ..) = tup;
}

View File

@ -0,0 +1,50 @@
#![feature(move_ref_pattern)]
fn main() {}
struct U;
fn slice() {
let mut arr = [U, U, U, U, U];
let hold_all = &arr;
let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; //~ ERROR cannot move out of `arr[..]`
_x1 = U; //~ ERROR cannot assign twice to immutable variable `_x1`
drop(hold_all);
let [_x0, ..] = arr; //~ ERROR cannot move out of `arr[..]`
drop(_x0_hold);
let [_, _, ref mut _x2, _x3, mut _x4] = arr;
//~^ ERROR cannot borrow `arr[..]` as mutable
//~| ERROR cannot move out of `arr[..]` because it is borrowed
//~| ERROR cannot move out of `arr[..]` because it is borrowed
drop(xs_hold);
}
fn tuple() {
let mut tup = (U, U, U, U);
let (ref _x0, _x1, ref _x2, ..) = tup;
_x1 = U; //~ ERROR cannot assign twice to immutable variable
let _x0_hold = &mut tup.0; //~ ERROR cannot borrow `tup.0` as mutable because it is also
let (ref mut _x0_hold, ..) = tup; //~ ERROR cannot borrow `tup.0` as mutable because it is also
*_x0 = U; //~ ERROR cannot assign to `*_x0` which is behind a `&` reference
*_x2 = U; //~ ERROR cannot assign to `*_x2` which is behind a `&` reference
drop(tup.1); //~ ERROR use of moved value: `tup.1`
let _x1_hold = &tup.1; //~ ERROR borrow of moved value: `tup.1`
let (.., ref mut _x3) = tup;
let _x3_hold = &tup.3; //~ ERROR cannot borrow `tup.3` as immutable
let _x3_hold = &mut tup.3; //~ ERROR cannot borrow `tup.3` as mutable more
let (.., ref mut _x4_hold) = tup; //~ ERROR cannot borrow `tup.3` as mutable more
let (.., ref _x4_hold) = tup; //~ ERROR cannot borrow `tup.3` as immutable
drop(_x3);
}
fn closure() {
let mut tup = (U, U, U);
let c1 = || {
let (ref _x0, _x1, _) = tup;
};
let c2 = || {
//~^ ERROR use of moved value
let (ref mut _x0, _, _x2) = tup;
};
drop(c1);
}

View File

@ -0,0 +1,208 @@
error[E0505]: cannot move out of `arr[..]` because it is borrowed
--> $DIR/borrowck-move-ref-pattern.rs:10:24
|
LL | let hold_all = &arr;
| ---- borrow of `arr` occurs here
LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr;
| ^^^ move out of `arr[..]` occurs here
LL | _x1 = U;
LL | drop(hold_all);
| -------- borrow later used here
error[E0384]: cannot assign twice to immutable variable `_x1`
--> $DIR/borrowck-move-ref-pattern.rs:11:5
|
LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr;
| ---
| |
| first assignment to `_x1`
| help: make this binding mutable: `mut _x1`
LL | _x1 = U;
| ^^^^^^^ cannot assign twice to immutable variable
error[E0505]: cannot move out of `arr[..]` because it is borrowed
--> $DIR/borrowck-move-ref-pattern.rs:13:10
|
LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr;
| ------------ borrow of `arr[..]` occurs here
...
LL | let [_x0, ..] = arr;
| ^^^ move out of `arr[..]` occurs here
LL | drop(_x0_hold);
| -------- borrow later used here
error[E0502]: cannot borrow `arr[..]` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-move-ref-pattern.rs:15:16
|
LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr;
| ---------------- immutable borrow occurs here
...
LL | let [_, _, ref mut _x2, _x3, mut _x4] = arr;
| ^^^^^^^^^^^ mutable borrow occurs here
...
LL | drop(xs_hold);
| ------- immutable borrow later used here
error[E0505]: cannot move out of `arr[..]` because it is borrowed
--> $DIR/borrowck-move-ref-pattern.rs:15:29
|
LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr;
| ---------------- borrow of `arr[..]` occurs here
...
LL | let [_, _, ref mut _x2, _x3, mut _x4] = arr;
| ^^^ move out of `arr[..]` occurs here
...
LL | drop(xs_hold);
| ------- borrow later used here
error[E0505]: cannot move out of `arr[..]` because it is borrowed
--> $DIR/borrowck-move-ref-pattern.rs:15:34
|
LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr;
| ---------------- borrow of `arr[..]` occurs here
...
LL | let [_, _, ref mut _x2, _x3, mut _x4] = arr;
| ^^^^^^^ move out of `arr[..]` occurs here
...
LL | drop(xs_hold);
| ------- borrow later used here
error[E0384]: cannot assign twice to immutable variable `_x1`
--> $DIR/borrowck-move-ref-pattern.rs:25:5
|
LL | let (ref _x0, _x1, ref _x2, ..) = tup;
| ---
| |
| first assignment to `_x1`
| help: make this binding mutable: `mut _x1`
LL | _x1 = U;
| ^^^^^^^ cannot assign twice to immutable variable
error[E0502]: cannot borrow `tup.0` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-move-ref-pattern.rs:26:20
|
LL | let (ref _x0, _x1, ref _x2, ..) = tup;
| ------- immutable borrow occurs here
LL | _x1 = U;
LL | let _x0_hold = &mut tup.0;
| ^^^^^^^^^^ mutable borrow occurs here
LL | let (ref mut _x0_hold, ..) = tup;
LL | *_x0 = U;
| -------- immutable borrow later used here
error[E0502]: cannot borrow `tup.0` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-move-ref-pattern.rs:27:10
|
LL | let (ref _x0, _x1, ref _x2, ..) = tup;
| ------- immutable borrow occurs here
...
LL | let (ref mut _x0_hold, ..) = tup;
| ^^^^^^^^^^^^^^^^ mutable borrow occurs here
LL | *_x0 = U;
| -------- immutable borrow later used here
error[E0594]: cannot assign to `*_x0` which is behind a `&` reference
--> $DIR/borrowck-move-ref-pattern.rs:28:5
|
LL | let (ref _x0, _x1, ref _x2, ..) = tup;
| ------- help: consider changing this to be a mutable reference: `ref mut _x0`
...
LL | *_x0 = U;
| ^^^^^^^^ `_x0` is a `&` reference, so the data it refers to cannot be written
error[E0594]: cannot assign to `*_x2` which is behind a `&` reference
--> $DIR/borrowck-move-ref-pattern.rs:29:5
|
LL | let (ref _x0, _x1, ref _x2, ..) = tup;
| ------- help: consider changing this to be a mutable reference: `ref mut _x2`
...
LL | *_x2 = U;
| ^^^^^^^^ `_x2` is a `&` reference, so the data it refers to cannot be written
error[E0382]: use of moved value: `tup.1`
--> $DIR/borrowck-move-ref-pattern.rs:30:10
|
LL | let (ref _x0, _x1, ref _x2, ..) = tup;
| --- value moved here
...
LL | drop(tup.1);
| ^^^^^ value used here after move
|
= note: move occurs because `tup.1` has type `U`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value: `tup.1`
--> $DIR/borrowck-move-ref-pattern.rs:31:20
|
LL | drop(tup.1);
| ----- value moved here
LL | let _x1_hold = &tup.1;
| ^^^^^^ value borrowed here after move
|
= note: move occurs because `tup.1` has type `U`, which does not implement the `Copy` trait
error[E0502]: cannot borrow `tup.3` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-move-ref-pattern.rs:33:20
|
LL | let (.., ref mut _x3) = tup;
| ----------- mutable borrow occurs here
LL | let _x3_hold = &tup.3;
| ^^^^^^ immutable borrow occurs here
...
LL | drop(_x3);
| --- mutable borrow later used here
error[E0499]: cannot borrow `tup.3` as mutable more than once at a time
--> $DIR/borrowck-move-ref-pattern.rs:34:20
|
LL | let (.., ref mut _x3) = tup;
| ----------- first mutable borrow occurs here
LL | let _x3_hold = &tup.3;
LL | let _x3_hold = &mut tup.3;
| ^^^^^^^^^^ second mutable borrow occurs here
...
LL | drop(_x3);
| --- first borrow later used here
error[E0499]: cannot borrow `tup.3` as mutable more than once at a time
--> $DIR/borrowck-move-ref-pattern.rs:35:14
|
LL | let (.., ref mut _x3) = tup;
| ----------- first mutable borrow occurs here
...
LL | let (.., ref mut _x4_hold) = tup;
| ^^^^^^^^^^^^^^^^ second mutable borrow occurs here
LL | let (.., ref _x4_hold) = tup;
LL | drop(_x3);
| --- first borrow later used here
error[E0502]: cannot borrow `tup.3` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-move-ref-pattern.rs:36:14
|
LL | let (.., ref mut _x3) = tup;
| ----------- mutable borrow occurs here
...
LL | let (.., ref _x4_hold) = tup;
| ^^^^^^^^^^^^ immutable borrow occurs here
LL | drop(_x3);
| --- mutable borrow later used here
error[E0382]: use of moved value: `tup`
--> $DIR/borrowck-move-ref-pattern.rs:45:14
|
LL | let mut tup = (U, U, U);
| ------- move occurs because `tup` has type `(U, U, U)`, which does not implement the `Copy` trait
LL | let c1 = || {
| -- value moved into closure here
LL | let (ref _x0, _x1, _) = tup;
| --- variable moved due to use in closure
LL | };
LL | let c2 = || {
| ^^ value used here after move
LL |
LL | let (ref mut _x0, _, _x2) = tup;
| --- use occurs due to use in closure
error: aborting due to 18 previous errors
Some errors have detailed explanations: E0382, E0384, E0499, E0502, E0505, E0594.
For more information about an error, try `rustc --explain E0382`.

View File

@ -0,0 +1,15 @@
// When conflicts between by-move bindings in `by_move_1 @ has_by_move` patterns
// happen and that code is unreachable according to borrowck, we accept this code.
// In particular, we want to ensure here that an ICE does not happen, which it did originally.
// check-pass
#![feature(move_ref_pattern)]
#![feature(bindings_after_at)]
fn main() {
return;
struct S;
let a @ (b, c) = (S, S);
}

View File

@ -0,0 +1,23 @@
fn main() {
#[derive(Clone)]
struct X {
x: (),
}
let mut tup = (X { x: () }, X { x: () });
match Some(tup.clone()) {
Some((y, ref z)) => {}
//~^ ERROR binding by-move and by-ref in the same pattern is unstable
None => panic!(),
}
let (ref a, b) = tup.clone();
//~^ ERROR binding by-move and by-ref in the same pattern is unstable
let (a, mut b) = &tup;
//~^ ERROR binding by-move and by-ref in the same pattern is unstable
//~| ERROR cannot move out of a shared reference
let (mut a, b) = &mut tup;
//~^ ERROR binding by-move and by-ref in the same pattern is unstable
//~| ERROR cannot move out of a mutable reference
}

View File

@ -0,0 +1,66 @@
error[E0658]: binding by-move and by-ref in the same pattern is unstable
--> $DIR/feature-gate-move_ref_pattern.rs:8:15
|
LL | Some((y, ref z)) => {}
| ^ ----- by-ref pattern here
| |
| by-move pattern here
|
= note: for more information, see https://github.com/rust-lang/rust/issues/68354
= help: add `#![feature(move_ref_pattern)]` to the crate attributes to enable
error[E0658]: binding by-move and by-ref in the same pattern is unstable
--> $DIR/feature-gate-move_ref_pattern.rs:13:17
|
LL | let (ref a, b) = tup.clone();
| ----- ^ by-move pattern here
| |
| by-ref pattern here
|
= note: for more information, see https://github.com/rust-lang/rust/issues/68354
= help: add `#![feature(move_ref_pattern)]` to the crate attributes to enable
error[E0658]: binding by-move and by-ref in the same pattern is unstable
--> $DIR/feature-gate-move_ref_pattern.rs:16:13
|
LL | let (a, mut b) = &tup;
| - ^^^^^ by-move pattern here
| |
| by-ref pattern here
|
= note: for more information, see https://github.com/rust-lang/rust/issues/68354
= help: add `#![feature(move_ref_pattern)]` to the crate attributes to enable
error[E0658]: binding by-move and by-ref in the same pattern is unstable
--> $DIR/feature-gate-move_ref_pattern.rs:20:10
|
LL | let (mut a, b) = &mut tup;
| ^^^^^ - by-ref pattern here
| |
| by-move pattern here
|
= note: for more information, see https://github.com/rust-lang/rust/issues/68354
= help: add `#![feature(move_ref_pattern)]` to the crate attributes to enable
error[E0507]: cannot move out of a shared reference
--> $DIR/feature-gate-move_ref_pattern.rs:16:22
|
LL | let (a, mut b) = &tup;
| ----- ^^^^
| |
| data moved here
| move occurs because `b` has type `main::X`, which does not implement the `Copy` trait
error[E0507]: cannot move out of a mutable reference
--> $DIR/feature-gate-move_ref_pattern.rs:20:22
|
LL | let (mut a, b) = &mut tup;
| ----- ^^^^^^^^
| |
| data moved here
| move occurs because `a` has type `main::X`, which does not implement the `Copy` trait
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0507, E0658.
For more information about an error, try `rustc --explain E0507`.

View File

@ -1,3 +1,7 @@
// check-pass
#![feature(move_ref_pattern)]
enum E {
Foo(String, String, String),
}
@ -11,10 +15,8 @@ fn main() {
let bar = Bar { a: "1".to_string(), b: "2".to_string() };
match E::Foo("".into(), "".into(), "".into()) {
E::Foo(a, b, ref c) => {}
//~^ ERROR cannot bind by-move and by-ref in the same pattern
}
match bar {
Bar {a, ref b} => {}
//~^ ERROR cannot bind by-move and by-ref in the same pattern
Bar { a, ref b } => {}
}
}

View File

@ -0,0 +1,122 @@
#![feature(move_ref_pattern)]
fn main() {
struct S; // Not `Copy`.
let mut tup0 = (S, S);
let mut tup1 = (S, S, S);
let tup2 = (S, S);
let tup3 = (S, S, S);
let tup4 = (S, S);
let mut arr0 = [S, S, S];
let mut arr1 = [S, S, S, S, S];
let arr2 = [S, S, S];
let arr3 = [S, S, S, S, S];
// The `mov` bindings require that we capture the scrutinees by-move.
let mut closure = || {
// Tuples...
let (ref mut borrow, mov) = tup0;
let (mov, _, ref mut borrow) = tup1;
let (ref borrow, mov) = tup2;
let (mov, _, ref borrow) = tup3;
let (ref borrow, mov) = tup4;
// Arrays...
let [mov @ .., ref borrow] = arr0;
let [_, ref mut borrow @ .., _, mov] = arr1;
let [mov @ .., ref borrow] = arr2;
let [_, ref borrow @ .., _, mov] = arr3;
};
// Now we try to borrow and move the captures, which should result in errors...
// ...for tuples:
drop(&tup0); //~ ERROR borrow of moved value: `tup0`
drop(&tup1); //~ ERROR borrow of moved value: `tup1`
drop(&tup2); //~ ERROR borrow of moved value: `tup2`
drop(&tup3); //~ ERROR borrow of moved value: `tup3`
// Ostensibly this should compile.
// However, because closures don't capture individual fields, which is changed in RFC 2229,
// this won't compile because the entire product is moved into the closure.
// The same applies to the array patterns below.
drop(&tup4.0); //~ ERROR borrow of moved value: `tup4`
// ...for arrays:
drop(&arr0); //~ ERROR borrow of moved value: `arr0`
let [_, mov1, mov2, mov3, _] = &arr1; //~ ERROR borrow of moved value: `arr1`
drop(&arr2); //~ ERROR borrow of moved value: `arr2`
let [_, mov1, mov2, mov3, _] = &arr3; //~ ERROR borrow of moved value: `arr3`
// Let's redo ^--- with a `match` + sum type:
macro_rules! m {
($p:pat = $s:expr) => {
match $s {
Some($p) => {}
_ => {}
}
};
}
let mut tup0: Option<(S, S)> = None;
let mut tup1: Option<(S, S, S)> = None;
let tup2: Option<(S, S)> = None;
let tup3: Option<(S, S, S)> = None;
let tup4: Option<(S, S)> = None;
let mut arr0: Option<[S; 3]> = None;
let mut arr1: Option<[S; 5]> = None;
let arr2: Option<[S; 3]> = None;
let arr3: Option<[S; 5]> = None;
let mut closure = || {
m!((ref mut borrow, mov) = tup0);
m!((mov, _, ref mut borrow) = tup1);
m!((ref borrow, mov) = tup2);
m!((mov, _, ref borrow) = tup3);
m!((ref borrow, mov) = tup4);
m!([mov @ .., ref borrow] = arr0);
m!([_, ref mut borrow @ .., _, mov] = arr1);
m!([mov @ .., ref borrow] = arr2);
m!([_, ref borrow @ .., _, mov] = arr3);
};
drop(&tup0); //~ ERROR borrow of moved value: `tup0`
drop(&tup1); //~ ERROR borrow of moved value: `tup1`
drop(&tup2); //~ ERROR borrow of moved value: `tup2`
drop(&tup3); //~ ERROR borrow of moved value: `tup3`
m!((ref x, _) = &tup4); //~ ERROR borrow of moved value: `tup4`
drop(&arr0); //~ ERROR borrow of moved value: `arr0`
m!([_, mov1, mov2, mov3, _] = &arr1); //~ ERROR borrow of moved value: `arr1`
drop(&arr2); //~ ERROR borrow of moved value: `arr2`
m!([_, mov1, mov2, mov3, _] = &arr3); //~ ERROR borrow of moved value: `arr3`
// Let's redo ^--- with `if let` (which may diverge from `match` in the future):
macro_rules! m {
($p:pat = $s:expr) => {
if let Some($p) = $s {}
};
}
let mut tup0: Option<(S, S)> = None;
let mut tup1: Option<(S, S, S)> = None;
let tup2: Option<(S, S)> = None;
let tup3: Option<(S, S, S)> = None;
let tup4: Option<(S, S)> = None;
let mut arr0: Option<[S; 3]> = None;
let mut arr1: Option<[S; 5]> = None;
let arr2: Option<[S; 3]> = None;
let arr3: Option<[S; 5]> = None;
let mut closure = || {
m!((ref mut borrow, mov) = tup0);
m!((mov, _, ref mut borrow) = tup1);
m!((ref borrow, mov) = tup2);
m!((mov, _, ref borrow) = tup3);
m!((ref borrow, mov) = tup4);
m!([mov @ .., ref borrow] = arr0);
m!([_, ref mut borrow @ .., _, mov] = arr1);
m!([mov @ .., ref borrow] = arr2);
m!([_, ref borrow @ .., _, mov] = arr3);
};
drop(&tup0); //~ ERROR borrow of moved value: `tup0`
drop(&tup1); //~ ERROR borrow of moved value: `tup1`
drop(&tup2); //~ ERROR borrow of moved value: `tup2`
drop(&tup3); //~ ERROR borrow of moved value: `tup3`
m!((ref x, _) = &tup4); //~ ERROR borrow of moved value: `tup4`
drop(&arr0); //~ ERROR borrow of moved value: `arr0`
m!([_, mov1, mov2, mov3, _] = &arr1); //~ ERROR borrow of moved value: `arr1`
drop(&arr2); //~ ERROR borrow of moved value: `arr2`
m!([_, mov1, mov2, mov3, _] = &arr3); //~ ERROR borrow of moved value: `arr3`
}

View File

@ -0,0 +1,404 @@
error[E0382]: borrow of moved value: `tup0`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:33:10
|
LL | let mut tup0 = (S, S);
| -------- move occurs because `tup0` has type `(main::S, main::S)`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
LL | // Tuples...
LL | let (ref mut borrow, mov) = tup0;
| ---- variable moved due to use in closure
...
LL | drop(&tup0);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `tup1`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:34:10
|
LL | let mut tup1 = (S, S, S);
| -------- move occurs because `tup1` has type `(main::S, main::S, main::S)`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
...
LL | let (mov, _, ref mut borrow) = tup1;
| ---- variable moved due to use in closure
...
LL | drop(&tup1);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `tup2`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:35:10
|
LL | let tup2 = (S, S);
| ---- move occurs because `tup2` has type `(main::S, main::S)`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
...
LL | let (ref borrow, mov) = tup2;
| ---- variable moved due to use in closure
...
LL | drop(&tup2);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `tup3`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:36:10
|
LL | let tup3 = (S, S, S);
| ---- move occurs because `tup3` has type `(main::S, main::S, main::S)`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
...
LL | let (mov, _, ref borrow) = tup3;
| ---- variable moved due to use in closure
...
LL | drop(&tup3);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `tup4`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:41:10
|
LL | let tup4 = (S, S);
| ---- move occurs because `tup4` has type `(main::S, main::S)`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
...
LL | let (ref borrow, mov) = tup4;
| ---- variable moved due to use in closure
...
LL | drop(&tup4.0);
| ^^^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `arr0`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:43:10
|
LL | let mut arr0 = [S, S, S];
| -------- move occurs because `arr0` has type `[main::S; 3]`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
...
LL | let [mov @ .., ref borrow] = arr0;
| ---- variable moved due to use in closure
...
LL | drop(&arr0);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `arr1`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:44:36
|
LL | let mut arr1 = [S, S, S, S, S];
| -------- move occurs because `arr1` has type `[main::S; 5]`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
...
LL | let [_, ref mut borrow @ .., _, mov] = arr1;
| ---- variable moved due to use in closure
...
LL | let [_, mov1, mov2, mov3, _] = &arr1;
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `arr2`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:45:10
|
LL | let arr2 = [S, S, S];
| ---- move occurs because `arr2` has type `[main::S; 3]`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
...
LL | let [mov @ .., ref borrow] = arr2;
| ---- variable moved due to use in closure
...
LL | drop(&arr2);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `arr3`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:46:36
|
LL | let arr3 = [S, S, S, S, S];
| ---- move occurs because `arr3` has type `[main::S; 5]`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
...
LL | let [_, ref borrow @ .., _, mov] = arr3;
| ---- variable moved due to use in closure
...
LL | let [_, mov1, mov2, mov3, _] = &arr3;
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `tup0`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:77:10
|
LL | let mut tup0: Option<(S, S)> = None;
| -------- move occurs because `tup0` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
LL | m!((ref mut borrow, mov) = tup0);
| ---- variable moved due to use in closure
...
LL | drop(&tup0);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `tup1`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:78:10
|
LL | let mut tup1: Option<(S, S, S)> = None;
| -------- move occurs because `tup1` has type `std::option::Option<(main::S, main::S, main::S)>`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
LL | m!((ref mut borrow, mov) = tup0);
LL | m!((mov, _, ref mut borrow) = tup1);
| ---- variable moved due to use in closure
...
LL | drop(&tup1);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `tup2`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:79:10
|
LL | let tup2: Option<(S, S)> = None;
| ---- move occurs because `tup2` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
...
LL | m!((ref borrow, mov) = tup2);
| ---- variable moved due to use in closure
...
LL | drop(&tup2);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `tup3`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:80:10
|
LL | let tup3: Option<(S, S, S)> = None;
| ---- move occurs because `tup3` has type `std::option::Option<(main::S, main::S, main::S)>`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
...
LL | m!((mov, _, ref borrow) = tup3);
| ---- variable moved due to use in closure
...
LL | drop(&tup3);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `tup4`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:81:21
|
LL | let tup4: Option<(S, S)> = None;
| ---- move occurs because `tup4` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
...
LL | m!((ref borrow, mov) = tup4);
| ---- variable moved due to use in closure
...
LL | m!((ref x, _) = &tup4);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `arr0`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:82:10
|
LL | let mut arr0: Option<[S; 3]> = None;
| -------- move occurs because `arr0` has type `std::option::Option<[main::S; 3]>`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
...
LL | m!([mov @ .., ref borrow] = arr0);
| ---- variable moved due to use in closure
...
LL | drop(&arr0);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `arr1`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:83:35
|
LL | let mut arr1: Option<[S; 5]> = None;
| -------- move occurs because `arr1` has type `std::option::Option<[main::S; 5]>`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
...
LL | m!([_, ref mut borrow @ .., _, mov] = arr1);
| ---- variable moved due to use in closure
...
LL | m!([_, mov1, mov2, mov3, _] = &arr1);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `arr2`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:84:10
|
LL | let arr2: Option<[S; 3]> = None;
| ---- move occurs because `arr2` has type `std::option::Option<[main::S; 3]>`, which does not implement the `Copy` trait
LL | let arr3: Option<[S; 5]> = None;
LL | let mut closure = || {
| -- value moved into closure here
...
LL | m!([mov @ .., ref borrow] = arr2);
| ---- variable moved due to use in closure
...
LL | drop(&arr2);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `arr3`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:85:35
|
LL | let arr3: Option<[S; 5]> = None;
| ---- move occurs because `arr3` has type `std::option::Option<[main::S; 5]>`, which does not implement the `Copy` trait
LL | let mut closure = || {
| -- value moved into closure here
...
LL | m!([_, ref borrow @ .., _, mov] = arr3);
| ---- variable moved due to use in closure
...
LL | m!([_, mov1, mov2, mov3, _] = &arr3);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `tup0`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:113:10
|
LL | let mut tup0: Option<(S, S)> = None;
| -------- move occurs because `tup0` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
LL | m!((ref mut borrow, mov) = tup0);
| ---- variable moved due to use in closure
...
LL | drop(&tup0);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `tup1`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:114:10
|
LL | let mut tup1: Option<(S, S, S)> = None;
| -------- move occurs because `tup1` has type `std::option::Option<(main::S, main::S, main::S)>`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
LL | m!((ref mut borrow, mov) = tup0);
LL | m!((mov, _, ref mut borrow) = tup1);
| ---- variable moved due to use in closure
...
LL | drop(&tup1);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `tup2`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:115:10
|
LL | let tup2: Option<(S, S)> = None;
| ---- move occurs because `tup2` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
...
LL | m!((ref borrow, mov) = tup2);
| ---- variable moved due to use in closure
...
LL | drop(&tup2);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `tup3`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:116:10
|
LL | let tup3: Option<(S, S, S)> = None;
| ---- move occurs because `tup3` has type `std::option::Option<(main::S, main::S, main::S)>`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
...
LL | m!((mov, _, ref borrow) = tup3);
| ---- variable moved due to use in closure
...
LL | drop(&tup3);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `tup4`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:117:21
|
LL | let tup4: Option<(S, S)> = None;
| ---- move occurs because `tup4` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
...
LL | m!((ref borrow, mov) = tup4);
| ---- variable moved due to use in closure
...
LL | m!((ref x, _) = &tup4);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `arr0`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:118:10
|
LL | let mut arr0: Option<[S; 3]> = None;
| -------- move occurs because `arr0` has type `std::option::Option<[main::S; 3]>`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
...
LL | m!([mov @ .., ref borrow] = arr0);
| ---- variable moved due to use in closure
...
LL | drop(&arr0);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `arr1`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:119:35
|
LL | let mut arr1: Option<[S; 5]> = None;
| -------- move occurs because `arr1` has type `std::option::Option<[main::S; 5]>`, which does not implement the `Copy` trait
...
LL | let mut closure = || {
| -- value moved into closure here
...
LL | m!([_, ref mut borrow @ .., _, mov] = arr1);
| ---- variable moved due to use in closure
...
LL | m!([_, mov1, mov2, mov3, _] = &arr1);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `arr2`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:120:10
|
LL | let arr2: Option<[S; 3]> = None;
| ---- move occurs because `arr2` has type `std::option::Option<[main::S; 3]>`, which does not implement the `Copy` trait
LL | let arr3: Option<[S; 5]> = None;
LL | let mut closure = || {
| -- value moved into closure here
...
LL | m!([mov @ .., ref borrow] = arr2);
| ---- variable moved due to use in closure
...
LL | drop(&arr2);
| ^^^^^ value borrowed here after move
error[E0382]: borrow of moved value: `arr3`
--> $DIR/move-ref-patterns-closure-captures-inside.rs:121:35
|
LL | let arr3: Option<[S; 5]> = None;
| ---- move occurs because `arr3` has type `std::option::Option<[main::S; 5]>`, which does not implement the `Copy` trait
LL | let mut closure = || {
| -- value moved into closure here
...
LL | m!([_, ref borrow @ .., _, mov] = arr3);
| ---- variable moved due to use in closure
...
LL | m!([_, mov1, mov2, mov3, _] = &arr3);
| ^^^^^ value borrowed here after move
error: aborting due to 27 previous errors
For more information about this error, try `rustc --explain E0382`.

View File

@ -0,0 +1,30 @@
// check-pass
#![feature(move_ref_pattern)]
fn main() {
struct U;
fn accept_fn_once(_: impl FnOnce()) {}
fn accept_fn_mut(_: impl FnMut()) {}
fn accept_fn(_: impl Fn()) {}
let mut tup = (U, U, U);
let (ref _x0, _x1, ref mut _x2) = tup;
let c1 = || {
drop::<&U>(_x0);
drop::<U>(_x1);
drop::<&mut U>(_x2);
};
accept_fn_once(c1);
let c2 = || {
drop::<&U>(_x0);
drop::<&mut U>(_x2);
};
accept_fn_mut(c2);
let c3 = || {
drop::<&U>(_x0);
};
accept_fn(c3);
}

View File

@ -0,0 +1,34 @@
#![feature(move_ref_pattern)]
fn main() {
struct U;
fn accept_fn_once(_: &impl FnOnce()) {}
fn accept_fn_mut(_: &impl FnMut()) {}
fn accept_fn(_: &impl Fn()) {}
let mut tup = (U, U, U);
let (ref _x0, _x1, ref mut _x2) = tup;
let c1 = || {
//~^ ERROR expected a closure that implements the `FnMut`
//~| ERROR expected a closure that implements the `Fn`
drop::<&U>(_x0);
drop::<U>(_x1);
drop::<&mut U>(_x2);
};
accept_fn_once(&c1);
accept_fn_mut(&c1);
accept_fn(&c1);
let c2 = || {
//~^ ERROR expected a closure that implements the `Fn`
drop::<&U>(_x0);
drop::<&mut U>(_x2);
};
accept_fn_mut(&c2);
accept_fn(&c2);
let c3 = || {
drop::<&U>(_x0);
};
accept_fn(&c3);
}

View File

@ -0,0 +1,39 @@
error[E0525]: expected a closure that implements the `FnMut` trait, but this closure only implements `FnOnce`
--> $DIR/move-ref-patterns-closure-captures.rs:11:14
|
LL | let c1 = || {
| ^^ this closure implements `FnOnce`, not `FnMut`
...
LL | drop::<U>(_x1);
| --- closure is `FnOnce` because it moves the variable `_x1` out of its environment
...
LL | accept_fn_mut(&c1);
| ------------- the requirement to implement `FnMut` derives from here
error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
--> $DIR/move-ref-patterns-closure-captures.rs:11:14
|
LL | let c1 = || {
| ^^ this closure implements `FnOnce`, not `Fn`
...
LL | drop::<U>(_x1);
| --- closure is `FnOnce` because it moves the variable `_x1` out of its environment
...
LL | accept_fn(&c1);
| --------- the requirement to implement `Fn` derives from here
error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnMut`
--> $DIR/move-ref-patterns-closure-captures.rs:22:14
|
LL | let c2 = || {
| ^^ this closure implements `FnMut`, not `Fn`
...
LL | drop::<&mut U>(_x2);
| --- closure is `FnMut` because it mutates the variable `_x2` here
...
LL | accept_fn(&c2);
| --------- the requirement to implement `Fn` derives from here
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0525`.

View File

@ -0,0 +1,16 @@
#![feature(move_ref_pattern)]
fn main() {
struct U;
// A tuple is a "non-reference pattern".
// A `mut` binding pattern resets the binding mode to by-value.
let p = (U, U);
let (a, mut b) = &p;
//~^ ERROR cannot move out of a shared reference
let mut p = (U, U);
let (a, mut b) = &mut p;
//~^ ERROR cannot move out of a mutable reference
}

View File

@ -0,0 +1,21 @@
error[E0507]: cannot move out of a shared reference
--> $DIR/move-ref-patterns-default-binding-modes.rs:10:22
|
LL | let (a, mut b) = &p;
| ----- ^^
| |
| data moved here
| move occurs because `b` has type `main::U`, which does not implement the `Copy` trait
error[E0507]: cannot move out of a mutable reference
--> $DIR/move-ref-patterns-default-binding-modes.rs:14:22
|
LL | let (a, mut b) = &mut p;
| ----- ^^^^^^
| |
| data moved here
| move occurs because `b` has type `main::U`, which does not implement the `Copy` trait
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0507`.

View File

@ -0,0 +1,81 @@
// run-pass
// This test checks the dynamic semantics and drop order of pattern matching
// where a product pattern has both a by-move and by-ref binding.
#![feature(move_ref_pattern)]
use std::cell::RefCell;
use std::rc::Rc;
struct X {
x: Box<usize>,
d: DropOrderListPtr,
}
type DropOrderListPtr = Rc<RefCell<Vec<usize>>>;
impl Drop for X {
fn drop(&mut self) {
self.d.borrow_mut().push(*self.x);
}
}
enum DoubleOption<T, U> {
Some2(T, U),
_None2,
}
fn main() {
let d: DropOrderListPtr = <_>::default();
{
let mk = |v| X { x: Box::new(v), d: d.clone() };
let check = |a1: &X, a2, b1: &X, b2| {
assert_eq!(*a1.x, a2);
assert_eq!(*b1.x, b2);
};
let x = DoubleOption::Some2(mk(1), mk(2));
match x {
DoubleOption::Some2(ref a, b) => check(a, 1, &b, 2),
DoubleOption::_None2 => panic!(),
}
let x = DoubleOption::Some2(mk(3), mk(4));
match x {
DoubleOption::Some2(a, ref b) => check(&a, 3, b, 4),
DoubleOption::_None2 => panic!(),
}
match DoubleOption::Some2(mk(5), mk(6)) {
DoubleOption::Some2(ref a, b) => check(a, 5, &b, 6),
DoubleOption::_None2 => panic!(),
}
match DoubleOption::Some2(mk(7), mk(8)) {
DoubleOption::Some2(a, ref b) => check(&a, 7, b, 8),
DoubleOption::_None2 => panic!(),
}
{
let (a, ref b) = (mk(9), mk(10));
let (ref c, d) = (mk(11), mk(12));
check(&a, 9, b, 10);
check(c, 11, &d, 12);
}
fn fun([a, ref mut b, ref xs @ .., ref c, d]: [X; 6]) {
assert_eq!(*a.x, 13);
assert_eq!(*b.x, 14);
assert_eq!(&[*xs[0].x, *xs[1].x], &[15, 16]);
assert_eq!(*c.x, 17);
assert_eq!(*d.x, 18);
}
fun([mk(13), mk(14), mk(15), mk(16), mk(17), mk(18)]);
let lam = |(a, ref b, c, ref mut d): (X, X, X, X)| {
assert_eq!(*a.x, 19);
assert_eq!(*b.x, 20);
assert_eq!(*c.x, 21);
assert_eq!(*d.x, 22);
};
lam((mk(19), mk(20), mk(21), mk(22)));
}
let expected = [2, 3, 6, 5, 7, 8, 12, 11, 9, 10, 18, 13, 14, 15, 16, 17, 21, 19, 20, 22, 4, 1];
assert_eq!(&*d.borrow(), &expected);
}

View File

@ -2,7 +2,7 @@
// outside of slice (+ ident patterns witin those), tuple,
// and tuple struct patterns and that duplicates are caught in these contexts.
#![feature(slice_patterns, box_patterns)]
#![feature(box_patterns)]
fn main() {}

View File

@ -1,10 +1,11 @@
#![feature(move_ref_pattern)]
struct Foo {}
pub fn main() {
let mut tups = vec![(Foo{}, Foo{})];
let mut tups = vec![(Foo {}, Foo {})];
// The below desugars to &(ref n, mut m).
for (n, mut m) in &tups {
//~^ ERROR cannot bind by-move and by-ref in the same pattern
//~| ERROR cannot move out of a shared reference
//~^ ERROR cannot move out of a shared reference
}
}

View File

@ -1,13 +1,5 @@
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/for.rs:6:13
|
LL | for (n, mut m) in &tups {
| - ^^^^^ by-move pattern here
| |
| by-ref pattern here
error[E0507]: cannot move out of a shared reference
--> $DIR/for.rs:6:23
--> $DIR/for.rs:8:23
|
LL | for (n, mut m) in &tups {
| ----- ^^^^^
@ -15,7 +7,6 @@ LL | for (n, mut m) in &tups {
| data moved here
| move occurs because `m` has type `Foo`, which does not implement the `Copy` trait
error: aborting due to 2 previous errors
error: aborting due to previous error
Some errors have detailed explanations: E0009, E0507.
For more information about an error, try `rustc --explain E0009`.
For more information about this error, try `rustc --explain E0507`.