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 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 the same way. The goal here is to avoid binding simultaneously by-move and
by-ref. by-ref.
@ -6,7 +8,9 @@ This limitation may be removed in a future version of Rust.
Erroneous code example: Erroneous code example:
```compile_fail,E0009 ```
#![feature(move_ref_pattern)]
struct X { x: (), } struct X { x: (), }
let x = Some((X { x: () }, 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, /// all, and you just supplied a `Span` to create the diagnostic,
/// then the snippet will just include that `Span`, which is /// then the snippet will just include that `Span`, which is
/// called the primary span. /// 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.0.diagnostic.span_label(span, label);
self 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( forward!(pub fn note_expected_found(
&mut self, &mut self,
expected_label: &dyn fmt::Display, expected_label: &dyn fmt::Display,

View File

@ -535,6 +535,10 @@ declare_features! (
/// For example, you can write `x @ Some(y)`. /// For example, you can write `x @ Some(y)`.
(active, bindings_after_at, "1.41.0", Some(65490), None), (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. /// Allows `impl const Trait for T` syntax.
(active, const_trait_impl, "1.42.0", Some(67792), None), (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::lint::builtin::{IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS};
use rustc_session::parse::feature_err; use rustc_session::parse::feature_err;
use rustc_session::Session; use rustc_session::Session;
use rustc_span::symbol::sym; use rustc_span::{sym, Span};
use rustc_span::{MultiSpan, Span};
use syntax::ast::Mutability; use syntax::ast::Mutability;
use std::slice; use std::slice;
@ -114,8 +113,10 @@ impl PatCtxt<'_, '_> {
impl<'tcx> MatchVisitor<'_, 'tcx> { impl<'tcx> MatchVisitor<'_, 'tcx> {
fn check_patterns(&mut self, has_guard: bool, pat: &Pat<'_>) { fn check_patterns(&mut self, has_guard: bool, pat: &Pat<'_>) {
check_legality_of_move_bindings(self, has_guard, pat); if !self.tcx.features().move_ref_pattern {
check_borrow_conflicts_in_at_patterns(self, pat); 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 { if !self.tcx.features().bindings_after_at {
check_legality_of_bindings_in_at_patterns(self, pat); 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 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. /// Check the legality of legality of by-move bindings.
fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: bool, pat: &Pat<'_>) { fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: bool, pat: &Pat<'_>) {
let sess = cx.tcx.sess; 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| { pat.walk_always(|p| {
if let hir::PatKind::Binding(.., sub) = &p.kind { if let hir::PatKind::Binding(.., sub) = &p.kind {
if let Some(ty::BindByValue(_)) = tables.extract_binding_mode(sess, p.hir_id, p.span) { 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 is_binding_by_move(cx, p.hir_id, p.span) {
if !pat_ty.is_copy_modulo_regions(cx.tcx, cx.param_env, pat.span) {
check_move(p, sub.as_deref()); 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! // Found some bad by-move spans, error!
if !by_move_spans.is_empty() { if !by_move_spans.is_empty() {
let mut err = struct_span_err!( let mut err = feature_err(
sess, &sess.parse_sess,
MultiSpan::from_spans(by_move_spans.clone()), sym::move_ref_pattern,
E0009, by_move_spans.clone(),
"cannot bind by-move and by-ref in the same pattern", "binding by-move and by-ref in the same pattern is unstable",
); );
for span in by_ref_spans.iter() { for span in by_ref_spans.iter() {
err.span_label(*span, "by-ref pattern here"); 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: /// For example, this would reject:
/// - `ref x @ Some(ref mut y)`, /// - `ref x @ Some(ref mut y)`,
/// - `ref mut x @ Some(ref y)` /// - `ref mut x @ Some(ref y)`,
/// - `ref mut x @ Some(ref mut 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. /// This analysis is *not* subsumed by NLL.
fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat<'_>) { fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat<'_>) {
let tab = cx.tables; // Extract `sub` in `binding @ sub`.
let sess = cx.tcx.sess; let (name, sub) = match &pat.kind {
// Get the mutability of `p` if it's by-ref. hir::PatKind::Binding(.., name, Some(sub)) => (*name, sub),
let extract_binding_mut = |hir_id, span| match tab.extract_binding_mode(sess, hir_id, span)? { _ => return,
ty::BindByValue(_) => None,
ty::BindByReference(m) => Some(m),
}; };
pat.walk_always(|pat| { let binding_span = pat.span.with_hi(name.span.hi());
// Extract `sub` in `binding @ sub`.
let (name, sub) = match &pat.kind {
hir::PatKind::Binding(.., name, Some(sub)) => (*name, sub),
_ => return,
};
// Extract the mutability. let tables = cx.tables;
let mut_outer = match extract_binding_mut(pat.hir_id, pat.span) { let sess = cx.tcx.sess;
None => return,
Some(m) => m,
};
// We now have `ref $mut_outer binding @ sub` (semantically). // Get the binding move, extract the mutability if by-ref.
// Recurse into each binding in `sub` and find mutability conflicts. let mut_outer = match tables.extract_binding_mode(sess, pat.hir_id, pat.span) {
let mut conflicts_mut_mut = Vec::new(); Some(ty::BindByValue(_)) if is_binding_by_move(cx, pat.hir_id, pat.span) => {
let mut conflicts_mut_ref = Vec::new(); // We have `x @ pat` where `x` is by-move. Reject all borrows in `pat`.
sub.each_binding(|_, hir_id, span, _| { let mut conflicts_ref = Vec::new();
if let Some(mut_inner) = extract_binding_mut(hir_id, span) { sub.each_binding(|_, hir_id, span, _| {
match (mut_outer, mut_inner) { match tables.extract_binding_mode(sess, hir_id, span) {
(Mutability::Not, Mutability::Not) => {} Some(ty::BindByValue(_)) | None => {}
(Mutability::Mut, Mutability::Mut) => conflicts_mut_mut.push(span), Some(ty::BindByReference(_)) => conflicts_ref.push(span),
_ => conflicts_mut_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. // We now have `ref $mut_outer binding @ sub` (semantically).
let binding_span = pat.span.with_hi(name.span.hi()); // Recurse into each binding in `sub` and find mutability or move conflicts.
if !conflicts_mut_mut.is_empty() { let mut conflicts_move = Vec::new();
// Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`. let mut conflicts_mut_mut = Vec::new();
let msg = &format!("cannot borrow `{}` as mutable more than once at a time", name); let mut conflicts_mut_ref = Vec::new();
let mut err = sess.struct_span_err(pat.span, msg); sub.each_binding(|_, hir_id, span, name| {
err.span_label(binding_span, "first mutable borrow occurs here"); match tables.extract_binding_mode(sess, hir_id, span) {
for sp in conflicts_mut_mut { Some(ty::BindByReference(mut_inner)) => match (mut_outer, mut_inner) {
err.span_label(sp, "another mutable borrow occurs here"); (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 { Some(ty::BindByValue(_)) | None => {} // `ref mut?` + by-copy is fine.
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();
} }
}); });
// 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, /// Forbids bindings in `@` patterns. This used to be is necessary for memory safety,

View File

@ -457,6 +457,7 @@ symbols! {
module, module,
module_path, module_path,
more_struct_aliases, more_struct_aliases,
move_ref_pattern,
move_val_init, move_val_init,
movbe_target_feature, movbe_target_feature,
mul_with_overflow, 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 // edition:2018
// ignore-wasm32-bare compiled with panic=abort by default // ignore-wasm32-bare compiled with panic=abort by default
#![feature(move_ref_pattern)]
#![allow(unused)] #![allow(unused)]
use std::{ use std::{
@ -227,6 +229,12 @@ async fn subslice_pattern_reassign(a: Rc<Allocator>) {
a.alloc().await; 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) fn run_test<F, G>(cx: &mut Context<'_>, ref f: F)
where where
F: Fn(Rc<Allocator>) -> G, 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, true));
run_test(context, |a| subslice_pattern_from_end_with_drop(a, false, false)); 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| 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 // ignore-wasm32-bare compiled with panic=abort by default
#![feature(generators, generator_trait, untagged_unions)] #![feature(generators, generator_trait, untagged_unions)]
#![feature(move_ref_pattern)]
#![allow(unused_assignments)] #![allow(unused_assignments)]
#![allow(unused_variables)] #![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<'_> { fn panic_after_return(a: &Allocator) -> Ptr<'_> {
// Panic in the drop of `p` or `q` can leak // Panic in the drop of `p` or `q` can leak
let exceptions = vec![8, 9]; 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, 6));
run_test(|a| subslice_mixed_min_lengths(a, 7)); run_test(|a| subslice_mixed_min_lengths(a, 7));
run_test(|a| move_ref_pattern(a));
run_test(|a| { run_test(|a| {
panic_after_return(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; struct A;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]

View File

@ -3,33 +3,38 @@
// where one side is by-ref and the other is by-move. // where one side is by-ref and the other is by-move.
#![feature(bindings_after_at)] #![feature(bindings_after_at)]
#![feature(move_ref_pattern)]
struct X { x: () } struct X {
x: (),
}
fn main() { fn main() {
let x = Some(X { x: () }); let x = Some(X { x: () });
match x { match x {
Some(ref _y @ _z) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern Some(ref _y @ _z) => {} //~ ERROR cannot move out of value because it is borrowed
None => panic!() None => panic!(),
} }
let x = Some(X { x: () }); let x = Some(X { x: () });
match x { match x {
Some(_z @ ref _y) => { }, //~ ERROR cannot bind by-move with sub-bindings Some(_z @ ref _y) => {}
//~^ ERROR borrow of moved value //~^ ERROR borrow of moved value
None => panic!() //~| ERROR borrow of moved value
None => panic!(),
} }
let mut x = Some(X { x: () }); let mut x = Some(X { x: () });
match x { match x {
Some(ref mut _y @ _z) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern Some(ref mut _y @ _z) => {} //~ ERROR cannot move out of value because it is borrowed
None => panic!() None => panic!(),
} }
let mut x = Some(X { x: () }); let mut x = Some(X { x: () });
match 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 //~^ 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 error: cannot move out of value because it is borrowed
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:12:23 --> $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 | | value moved into `_z` here
| by-ref pattern here | value borrowed, by `_y`, here
error[E0007]: cannot bind by-move with sub-bindings error: borrow of moved value
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:18:14 --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:21:14
| |
LL | Some(_z @ ref _y) => { }, LL | Some(_z @ ref _y) => {}
| ^^^^^^^^^^^ binds an already bound by-move value by moving it | --^^^------
| | |
| | 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 error: cannot move out of value because it is borrowed
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:25:27 --> $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 | | value moved into `_z` here
| by-ref pattern here | value borrowed, by `_y`, here
error[E0007]: cannot bind by-move with sub-bindings error: borrow of moved value
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:31:14 --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:35:14
| |
LL | Some(_z @ ref mut _y) => { }, LL | Some(_z @ ref mut _y) => {}
| ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it | --^^^----------
| | |
| | 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 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 | | 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 = note: move occurs because value has type `X`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value 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 | | value borrowed here after move
@ -52,5 +60,4 @@ LL | Some(_z @ ref mut _y) => { },
error: aborting due to 6 previous errors error: aborting due to 6 previous errors
Some errors have detailed explanations: E0007, E0009, E0382. For more information about this error, try `rustc --explain E0382`.
For more information about an error, try `rustc --explain E0007`.

View File

@ -1,14 +1,14 @@
// See issue #12534. // See issue #12534.
#![feature(bindings_after_at)] #![feature(bindings_after_at)]
#![feature(move_ref_pattern)]
fn main() {} fn main() {}
struct A(Box<u8>); struct A(Box<u8>);
fn f(a @ A(u): 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); drop(a);
u 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 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> { 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 | value moved here
| move occurs because value has type `A`, which does not implement the `Copy` trait | 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 this error, try `rustc --explain E0382`.
For more information about an error, try `rustc --explain E0007`.

View File

@ -1,46 +1,34 @@
// Test that moving on both sides of an `@` pattern is not allowed. // Test that moving on both sides of an `@` pattern is not allowed.
#![feature(bindings_after_at)] #![feature(bindings_after_at)]
#![feature(move_ref_pattern)]
fn main() { fn main() {
struct U; // Not copy! struct U; // Not copy!
// Prevent promotion: // Prevent promotion:
fn u() -> U { U } fn u() -> U {
U
}
let a @ b = U; let a @ b = U; //~ ERROR use of moved value
//~^ ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
let a @ (b, c) = (U, U); let a @ (b, c) = (U, U); //~ ERROR use of moved value
//~^ ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
let a @ (b, c) = (u(), u()); let a @ (b, c) = (u(), u()); //~ ERROR use of moved value
//~^ ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
match Ok(U) { match Ok(U) {
a @ Ok(b) | a @ Err(b) => {} a @ Ok(b) | a @ Err(b) => {} //~ ERROR use of moved value
//~^ ERROR cannot bind by-move with sub-bindings //~^ ERROR use of moved value
//~| ERROR use of moved value
//~| ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
} }
fn fun(a @ b: U) {} fn fun(a @ b: U) {} //~ ERROR use of moved value
//~^ ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
match [u(), u(), u(), u()] { match [u(), u(), u(), u()] {
xs @ [a, .., b] => {} xs @ [a, .., b] => {} //~ ERROR use of moved value
//~^ ERROR cannot bind by-move with sub-bindings
//~| ERROR use of moved value
} }
match [u(), u(), u(), u()] { match [u(), u(), u(), u()] {
xs @ [_, ys @ .., _] => {} xs @ [_, ys @ .., _] => {} //~ ERROR use of moved value
//~^ ERROR cannot bind by-move with sub-bindings
//~| 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 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; LL | let a @ b = U;
| ----^ - move occurs because value has type `main::U`, which does not implement the `Copy` trait | ----^ - 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 | value moved here
error[E0382]: use of moved value 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); LL | let a @ (b, c) = (U, U);
| --------^- ------ move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait | --------^- ------ 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 | value moved here
error[E0382]: use of moved value 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()); LL | let a @ (b, c) = (u(), u());
| --------^- ---------- move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait | --------^- ---------- 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 | value moved here
error[E0382]: use of moved value 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) { LL | match Ok(U) {
| ----- move occurs because value has type `std::result::Result<main::U, main::U>`, which does not implement the `Copy` trait | ----- 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 | value moved here
error[E0382]: use of moved value 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) { LL | match Ok(U) {
| ----- move occurs because value has type `std::result::Result<main::U, main::U>`, which does not implement the `Copy` trait | ----- 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 | value moved here
error[E0382]: use of moved value 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()] { LL | match [u(), u(), u(), u()] {
| -------------------- move occurs because value has type `[main::U; 4]`, which does not implement the `Copy` trait | -------------------- 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 | value moved here
error[E0382]: use of moved value 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()] { LL | match [u(), u(), u(), u()] {
| -------------------- move occurs because value has type `[main::U; 4]`, which does not implement the `Copy` trait | -------------------- 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 | value moved here
error[E0382]: use of moved value 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) {} LL | fn fun(a @ b: U) {}
| ----^ | ----^
@ -127,7 +79,6 @@ LL | fn fun(a @ b: U) {}
| value moved here | value moved here
| move occurs because value has type `main::U`, which does not implement the `Copy` trait | 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 this error, try `rustc --explain E0382`.
For more information about an error, try `rustc --explain E0007`.

View File

@ -3,6 +3,7 @@
// Test `@` patterns combined with `box` patterns. // Test `@` patterns combined with `box` patterns.
#![feature(bindings_after_at)] #![feature(bindings_after_at)]
#![feature(move_ref_pattern)]
#![feature(box_patterns)] #![feature(box_patterns)]
#[derive(Copy, Clone)] #[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. // Test `@` patterns combined with `box` patterns.
#![feature(bindings_after_at)] #![feature(bindings_after_at)]
#![feature(move_ref_pattern)]
#![feature(box_patterns)] #![feature(box_patterns)]
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
struct C; struct C;
fn c() -> C { C } fn c() -> C {
C
}
struct NC; struct NC;
fn nc() -> NC { NC } fn nc() -> NC {
NC
}
fn main() { fn main() {
let a @ box &b = Box::new(&C); 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); 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>) {} 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>) {} 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 => {} } match Box::new(C) {
//~^ ERROR cannot bind by-move with sub-bindings a @ box b => {} //~ ERROR use of moved value
//~| 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()); 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); 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); 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; *b = NC;
let ref a @ box ref mut b = Box::new(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 //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable
*b = NC; *b = NC;
drop(a); drop(a);
let ref mut a @ box ref b = Box::new(NC); 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 //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable
*a = Box::new(NC); *a = Box::new(NC);
drop(b); drop(b);
fn f5(ref mut a @ box ref b: Box<NC>) { 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 //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable
*a = Box::new(NC); *a = Box::new(NC);
drop(b); drop(b);
@ -63,22 +64,10 @@ fn main() {
match Box::new(nc()) { match Box::new(nc()) {
ref mut a @ box ref b => { 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 //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable
*a = Box::new(NC); *a = Box::new(NC);
drop(b); 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 error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-at-and-box.rs:16:9 --> $DIR/borrowck-pat-at-and-box.rs:37: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
| |
LL | let ref a @ box b = Box::new(NC); LL | let ref a @ box b = Box::new(NC);
| ------------^ | -----^^^^^^^-
| | | | | |
| | by-move pattern here | | value moved into `b` here
| by-ref pattern here | value borrowed, by `a`, here
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
--> $DIR/borrowck-pat-at-and-box.rs:38:9 --> $DIR/borrowck-pat-at-and-box.rs:39:9
| |
LL | let ref a @ box ref mut b = Box::new(nc()); LL | let ref a @ box ref mut b = Box::new(nc());
| -----^^^^^^^--------- | -----^^^^^^^---------
| | | | | |
| | mutable borrow occurs here | | mutable borrow, by `b`, occurs here
| immutable borrow occurs here | immutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-at-and-box.rs:40:9 --> $DIR/borrowck-pat-at-and-box.rs:41:9
| |
LL | let ref a @ box ref mut b = Box::new(NC); LL | let ref a @ box ref mut b = Box::new(NC);
| -----^^^^^^^--------- | -----^^^^^^^---------
| | | | | |
| | mutable borrow occurs here | | mutable borrow, by `b`, occurs here
| immutable borrow occurs here | immutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-at-and-box.rs:42:9 --> $DIR/borrowck-pat-at-and-box.rs:43:9
| |
LL | let ref a @ box ref mut b = Box::new(NC); LL | let ref a @ box ref mut b = Box::new(NC);
| -----^^^^^^^--------- | -----^^^^^^^---------
| | | | | |
| | mutable borrow occurs here | | mutable borrow, by `b`, occurs here
| immutable borrow occurs here | immutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-at-and-box.rs:45:9 --> $DIR/borrowck-pat-at-and-box.rs:46:9
| |
LL | let ref a @ box ref mut b = Box::new(NC); LL | let ref a @ box ref mut b = Box::new(NC);
| -----^^^^^^^--------- | -----^^^^^^^---------
| | | | | |
| | mutable borrow occurs here | | mutable borrow, by `b`, occurs here
| immutable borrow occurs here | immutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-at-and-box.rs:51:9 --> $DIR/borrowck-pat-at-and-box.rs:52:9
| |
LL | let ref mut a @ box ref b = Box::new(NC); LL | let ref mut a @ box ref b = Box::new(NC);
| ---------^^^^^^^----- | ---------^^^^^^^-----
| | | | | |
| | immutable borrow occurs here | | immutable borrow, by `b`, occurs here
| mutable borrow occurs here | mutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-at-and-box.rs:65:9 --> $DIR/borrowck-pat-at-and-box.rs:66:9
| |
LL | ref mut a @ box ref b => { LL | ref mut a @ box ref b => {
| ---------^^^^^^^----- | ---------^^^^^^^-----
| | | | | |
| | immutable borrow occurs here | | immutable borrow, by `b`, occurs here
| mutable borrow occurs here | mutable borrow, by `a`, occurs here
error[E0009]: cannot bind by-move and by-ref in the same pattern error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-at-and-box.rs:74:38 --> $DIR/borrowck-pat-at-and-box.rs:58:11
|
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
| |
LL | fn f5(ref mut a @ box ref b: Box<NC>) { LL | fn f5(ref mut a @ box ref b: Box<NC>) {
| ---------^^^^^^^----- | ---------^^^^^^^-----
| | | | | |
| | immutable borrow occurs here | | immutable borrow, by `b`, occurs here
| mutable borrow occurs here | mutable borrow, by `a`, occurs here
error[E0382]: use of moved value 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); 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 | ---------^ ------------ 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 | value moved here
error[E0382]: use of moved value 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); 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 | --------^ ----------- 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 | value moved here
error[E0382]: use of moved value 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 => {} } 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 | | |
| move occurs because value has type `std::boxed::Box<C>`, which does not implement the `Copy` trait | | value used here after move
| value moved here
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable 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); LL | let ref a @ box ref mut b = Box::new(NC);
| ------------^^^^^^^^^ | ------------^^^^^^^^^
@ -159,7 +112,7 @@ LL | drop(a);
| - immutable borrow later used here | - immutable borrow later used here
error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable 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); 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 | -- mutable borrow later used here
error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable 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 => { LL | ref mut a @ box ref b => {
| ----------------^^^^^ | ----------------^^^^^
@ -183,7 +136,7 @@ LL | *a = Box::new(NC);
| -- mutable borrow later used here | -- mutable borrow later used here
error[E0382]: use of moved value 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>) {} 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 | move occurs because value has type `std::boxed::Box<&C>`, which does not implement the `Copy` trait
error[E0382]: use of moved value 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>) {} 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 | 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 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>) { 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); LL | *a = Box::new(NC);
| -- mutable borrow later used here | -- 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. Some errors have detailed explanations: E0382, E0502.
For more information about an error, try `rustc --explain E0007`. 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(bindings_after_at)]
#![feature(move_ref_pattern)]
fn main() { fn main() {
match Some("hi".to_string()) { struct U;
ref op_string_ref @ Some(s) => {},
//~^ ERROR cannot bind by-move and by-ref in the same pattern [E0009] // Prevent promotion.
None => {}, 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 error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:5:34 --> $DIR/borrowck-pat-by-move-and-ref.rs:23:9
| |
LL | ref op_string_ref @ Some(s) => {}, LL | let ref a @ b = U;
| -------------------------^- | -----^^^-
| | | | | |
| | by-move pattern here | | value moved into `b` here
| by-ref pattern 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(bindings_after_at)]
#![feature(move_ref_pattern)]
enum Option<T> { enum Option<T> {
None, None,
@ -8,7 +9,7 @@ enum Option<T> {
fn main() { fn main() {
match &mut Some(1) { match &mut Some(1) {
ref mut z @ &mut Some(ref a) => { ref mut z @ &mut Some(ref a) => {
//~^ ERROR cannot borrow `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 //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable
**z = None; **z = None;
println!("{}", *a); println!("{}", *a);
@ -22,49 +23,52 @@ fn main() {
fn u() -> U { U } fn u() -> U { U }
fn f1(ref a @ ref mut b: 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) {} 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]) {} 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 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 value 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 because it is also borrowed as immutable
let ref a @ ref mut b = U; 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; 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); 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); 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(); 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 //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable
*a = u(); *a = u();
drop(b); drop(b);
let ref a @ ref mut b = u(); 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 //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable
*b = u(); *b = u();
drop(a); drop(a);
let ref mut a @ ref b = U; 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; *a = U;
drop(b); drop(b);
let ref a @ ref mut b = U; 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; *b = U;
drop(a); drop(a);
match Ok(U) { match Ok(U) {
ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { 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 value 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
*a = Err(U); *a = Err(U);
drop(b); drop(b);
} }
@ -72,8 +76,8 @@ fn main() {
match Ok(U) { match Ok(U) {
ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
//~^ ERROR cannot borrow `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 `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
//~| 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; *b = U;
@ -83,52 +87,52 @@ fn main() {
match Ok(U) { match Ok(U) {
ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
//~^ ERROR cannot borrow `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 `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 assign to `*b`, as it is immutable for the pattern guard //~| ERROR cannot assign to `*b`, as it is immutable for the pattern guard
_ => {} _ => {}
} }
match Ok(U) { match Ok(U) {
ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} 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 value 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 assign to `*a`, as it is immutable for the pattern guard //~| ERROR cannot assign to `*a`, as it is immutable for the pattern guard
_ => {} _ => {}
} }
match Ok(U) { match Ok(U) {
ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
//~^ ERROR cannot borrow `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 `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 move out of `b` in pattern guard //~| ERROR cannot move out of `b` in pattern guard
//~| ERROR cannot move out of `b` in pattern guard //~| ERROR cannot move out of `b` in pattern guard
_ => {} _ => {}
} }
match Ok(U) { match Ok(U) {
ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} 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 value 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 move out of `a` in pattern guard //~| ERROR cannot move out of `a` in pattern guard
//~| 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); 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; *b = U;
*c = U; *c = U;
let ref a @ (ref mut b, ref mut c) = (U, 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
//~| 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; *b = U;
drop(a); drop(a);
let ref a @ (ref mut b, ref mut c) = (U, 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
*b = U; //~| ERROR cannot borrow `_` 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 *c = U; //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable
drop(a); drop(a);
let ref mut a @ (ref b, ref c) = (U, U); 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 error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:10:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:9
| |
LL | ref mut z @ &mut Some(ref a) => { LL | ref mut z @ &mut Some(ref a) => {
| ---------^^^^^^^^^^^^^-----^ | ---------^^^^^^^^^^^^^-----^
| | | | | |
| | immutable borrow occurs here | | immutable borrow, by `a`, occurs here
| mutable borrow occurs here | mutable borrow, by `z`, 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-and-ref.rs:31:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:9
| |
LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub
| ---------^^^^-----------------^ | ---------^^^^-----------------^
| | | | | | | |
| | | another mutable borrow occurs here | | | another mutable borrow, by `c`, occurs here
| | also borrowed as immutable here | | also borrowed as immutable, by `b`, here
| first mutable borrow occurs here | first mutable borrow, by `a`, occurs here
error: cannot borrow `b` as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:22 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:22
| |
LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub
| -----^^^--------- | -----^^^---------
| | | | | |
| | mutable borrow occurs here | | mutable borrow, by `c`, occurs here
| immutable borrow occurs here | immutable borrow, by `b`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:39:9
| |
LL | let ref a @ ref mut b = U; LL | let ref a @ ref mut b = U;
| -----^^^--------- | -----^^^---------
| | | | | |
| | mutable borrow occurs here | | mutable borrow, by `b`, occurs here
| immutable borrow occurs here | immutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:37:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:41:9
| |
LL | let ref mut a @ ref b = U; LL | let ref mut a @ ref b = U;
| ---------^^^----- | ---------^^^-----
| | | | | |
| | immutable borrow occurs here | | immutable borrow, by `b`, occurs here
| mutable borrow occurs here | mutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:39:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:43:9
| |
LL | let ref a @ (ref mut b, ref mut c) = (U, U); LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| -----^^^^---------^^---------^ | -----^^^^---------^^---------^
| | | | | | | |
| | | mutable borrow occurs here | | | mutable borrow, by `c`, occurs here
| | mutable borrow occurs here | | mutable borrow, by `b`, occurs here
| immutable borrow occurs here | immutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:41:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:45:9
| |
LL | let ref mut a @ (ref b, ref c) = (U, U); LL | let ref mut a @ (ref b, ref c) = (U, U);
| ---------^^^^-----^^-----^ | ---------^^^^-----^^-----^
| | | | | | | |
| | | immutable borrow occurs here | | | immutable borrow, by `c`, occurs here
| | immutable borrow occurs here | | immutable borrow, by `b`, occurs here
| mutable borrow occurs here | mutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:44:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:48:9
| |
LL | let ref mut a @ ref b = u(); LL | let ref mut a @ ref b = u();
| ---------^^^----- | ---------^^^-----
| | | | | |
| | immutable borrow occurs here | | immutable borrow, by `b`, occurs here
| mutable borrow occurs here | mutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:49:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:53:9
| |
LL | let ref a @ ref mut b = u(); LL | let ref a @ ref mut b = u();
| -----^^^--------- | -----^^^---------
| | | | | |
| | mutable borrow occurs here | | mutable borrow, by `b`, occurs here
| immutable borrow occurs here | immutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:55:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:59:9
| |
LL | let ref mut a @ ref b = U; LL | let ref mut a @ ref b = U;
| ---------^^^----- | ---------^^^-----
| | | | | |
| | immutable borrow occurs here | | immutable borrow, by `b`, occurs here
| mutable borrow occurs here | mutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:59:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:63:9
| |
LL | let ref a @ ref mut b = U; LL | let ref a @ ref mut b = U;
| -----^^^--------- | -----^^^---------
| | | | | |
| | mutable borrow occurs here | | mutable borrow, by `b`, occurs here
| immutable borrow occurs here | immutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:65:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:69:9
| |
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => {
| ---------^^^^^^-----^ | ---------^^^^^^-----^
| | | | | |
| | immutable borrow occurs here | | immutable borrow, by `b`, occurs here
| mutable borrow occurs here | mutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:65:33 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:69:33
| |
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => {
| ---------^^^^^^^-----^ | ---------^^^^^^^-----^
| | | | | |
| | immutable borrow occurs here | | immutable borrow, by `b`, occurs here
| mutable borrow occurs here | mutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:9
| |
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
| -----^^^^^^---------^ | -----^^^^^^---------^
| | | | | |
| | mutable borrow occurs here | | mutable borrow, by `b`, occurs here
| immutable borrow occurs here | immutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:33 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:33
| |
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
| -----^^^^^^^---------^ | -----^^^^^^^---------^
| | | | | |
| | mutable borrow occurs here | | mutable borrow, by `b`, occurs here
| immutable borrow occurs here | immutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:9 --> $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 } => {} LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
| -----^^^^^^---------^ | -----^^^^^^---------^
| | | | | |
| | mutable borrow occurs here | | mutable borrow, by `b`, occurs here
| immutable borrow occurs here | immutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:33 --> $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 } => {} LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
| -----^^^^^^^---------^ | -----^^^^^^^---------^
| | | | | |
| | mutable borrow occurs here | | mutable borrow, by `b`, occurs here
| immutable borrow occurs here | immutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96:9
| |
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
| ---------^^^^^^-----^ | ---------^^^^^^-----^
| | | | | |
| | immutable borrow occurs here | | immutable borrow, by `b`, occurs here
| mutable borrow occurs here | mutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:33 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96:33
| |
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
| ---------^^^^^^^-----^ | ---------^^^^^^^-----^
| | | | | |
| | immutable borrow occurs here | | immutable borrow, by `b`, occurs here
| mutable borrow occurs here | mutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:9
| |
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
| -----^^^^^^---------^ | -----^^^^^^---------^
| | | | | |
| | mutable borrow occurs here | | mutable borrow, by `b`, occurs here
| immutable borrow occurs here | immutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:33 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:33
| |
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
| -----^^^^^^^---------^ | -----^^^^^^^---------^
| | | | | |
| | mutable borrow occurs here | | mutable borrow, by `b`, occurs here
| immutable borrow occurs here | immutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:9 --> $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 } => {} LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
| ---------^^^^^^-----^ | ---------^^^^^^-----^
| | | | | |
| | immutable borrow occurs here | | immutable borrow, by `b`, occurs here
| mutable borrow occurs here | mutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:33 --> $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 } => {} LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
| ---------^^^^^^^-----^ | ---------^^^^^^^-----^
| | | | | |
| | immutable borrow occurs here | | immutable borrow, by `b`, occurs here
| mutable borrow occurs here | mutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:115:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:119:9
| |
LL | let ref a @ (ref mut b, ref mut c) = (U, U); LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| -----^^^^---------^^---------^ | -----^^^^---------^^---------^
| | | | | | | |
| | | mutable borrow occurs here | | | mutable borrow, by `c`, occurs here
| | mutable borrow occurs here | | mutable borrow, by `b`, occurs here
| immutable borrow occurs here | immutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:124:9
| |
LL | let ref a @ (ref mut b, ref mut c) = (U, U); LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| -----^^^^---------^^---------^ | -----^^^^---------^^---------^
| | | | | | | |
| | | mutable borrow occurs here | | | mutable borrow, by `c`, occurs here
| | mutable borrow occurs here | | mutable borrow, by `b`, occurs here
| immutable borrow occurs here | immutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:131:9
| |
LL | let ref a @ (ref mut b, ref mut c) = (U, U); LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| -----^^^^---------^^---------^ | -----^^^^---------^^---------^
| | | | | | | |
| | | mutable borrow occurs here | | | mutable borrow, by `c`, occurs here
| | mutable borrow occurs here | | mutable borrow, by `b`, occurs here
| immutable borrow occurs here | immutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:132:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:136:9
| |
LL | let ref mut a @ (ref b, ref c) = (U, U); LL | let ref mut a @ (ref b, ref c) = (U, U);
| ---------^^^^-----^^-----^ | ---------^^^^-----^^-----^
| | | | | | | |
| | | immutable borrow occurs here | | | immutable borrow, by `c`, occurs here
| | immutable borrow occurs here | | immutable borrow, by `b`, occurs here
| mutable borrow occurs here | mutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:24:11 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:25:11
| |
LL | fn f1(ref a @ ref mut b: U) {} LL | fn f1(ref a @ ref mut b: U) {}
| -----^^^--------- | -----^^^---------
| | | | | |
| | mutable borrow occurs here | | mutable borrow, by `b`, occurs here
| immutable borrow occurs here | immutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:26:11 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:27:11
| |
LL | fn f2(ref mut a @ ref b: U) {} LL | fn f2(ref mut a @ ref b: U) {}
| ---------^^^----- | ---------^^^-----
| | | | | |
| | immutable borrow occurs here | | immutable borrow, by `b`, occurs here
| mutable borrow occurs here | mutable borrow, by `a`, occurs here
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
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:11 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:29:11
| |
LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {}
| -----^^^^^^^^^^^----------------^^^^^^^^ | -----^^^^^^^^^^^----------------^^^^^^^^
| | | | | |
| | mutable borrow occurs here | | mutable borrow, by `mid`, occurs here
| immutable borrow 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 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) => { LL | ref mut z @ &mut Some(ref a) => {
| ----------------------^^^^^- | ----------------------^^^^^-
@ -288,7 +307,7 @@ LL | **z = None;
| ---------- mutable borrow later used here | ---------- mutable borrow later used here
error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable 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(); LL | let ref mut a @ ref b = u();
| ------------^^^^^ | ------------^^^^^
@ -300,7 +319,7 @@ LL | *a = u();
| -------- mutable borrow later used here | -------- mutable borrow later used here
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable 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(); LL | let ref a @ ref mut b = u();
| --------^^^^^^^^^ | --------^^^^^^^^^
@ -312,7 +331,7 @@ LL | drop(a);
| - immutable borrow later used here | - immutable borrow later used here
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable 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) => { 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 | - immutable borrow later used here
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable 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) => { 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 | - immutable borrow later used here
error[E0594]: cannot assign to `*b`, as it is immutable for the pattern guard error[E0594]: cannot assign to `*b`, as it is immutable for the pattern guard
--> $DIR/borrowck-pat-ref-mut-and-ref.rs: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 } => {} LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
| ^^^^^^ cannot assign | ^^^^^^ 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 = note: variables bound in patterns are immutable until the end of the pattern guard
error[E0594]: cannot assign to `*a`, as it is immutable for the pattern guard error[E0594]: cannot assign to `*a`, as it is immutable for the pattern guard
--> $DIR/borrowck-pat-ref-mut-and-ref.rs: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 } => {} LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
| ^^^^^^^^^^^ cannot assign | ^^^^^^^^^^^ 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 = note: variables bound in patterns are immutable until the end of the pattern guard
error[E0507]: cannot move out of `b` in pattern guard error[E0507]: cannot move out of `b` in pattern guard
--> $DIR/borrowck-pat-ref-mut-and-ref.rs: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 } => {} 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 | ^ 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 = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
error[E0507]: cannot move out of `b` in pattern guard error[E0507]: cannot move out of `b` in pattern guard
--> $DIR/borrowck-pat-ref-mut-and-ref.rs: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 } => {} 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 | ^ 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 = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
error[E0507]: cannot move out of `a` in pattern guard error[E0507]: cannot move out of `a` in pattern guard
--> $DIR/borrowck-pat-ref-mut-and-ref.rs: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 } => {} 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 | ^ 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 = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
error[E0507]: cannot move out of `a` in pattern guard error[E0507]: cannot move out of `a` in pattern guard
--> $DIR/borrowck-pat-ref-mut-and-ref.rs: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 } => {} 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 | ^ 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 = 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 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); LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| ---------^^^^^^^^^------------ | ---------^^^^^^^^^------------
@ -396,7 +415,7 @@ LL | drop(a);
| - immutable borrow later used here | - immutable borrow later used here
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable 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); LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| --------------------^^^^^^^^^- | --------------------^^^^^^^^^-
@ -408,7 +427,7 @@ LL | drop(a);
| - immutable borrow later used here | - immutable borrow later used here
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable 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); LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| ---------^^^^^^^^^------------ | ---------^^^^^^^^^------------
@ -420,7 +439,7 @@ LL | drop(a);
| - immutable borrow later used here | - immutable borrow later used here
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable 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); 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); LL | drop(a);
| - immutable borrow later used here | - 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. Some errors have detailed explanations: E0502, E0507, E0594.
For more information about an error, try `rustc --explain E0502`. 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. // Test that `ref mut x @ ref mut y` and varieties of that are not allowed.
#![feature(bindings_after_at)] #![feature(bindings_after_at)]
#![feature(move_ref_pattern)]
fn main() { fn main() {
struct U; struct U;
@ -8,39 +9,42 @@ fn main() {
fn u() -> U { U } fn u() -> U { U }
fn f1(ref mut a @ ref mut b: 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) {} 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( fn f3(
ref mut a @ [ 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 b @ .., _],
[_, ref mut mid @ ..], [_, ref mut mid @ ..],
.., ..,
[..], [..],
] : [[U; 4]; 5] ] : [[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; 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 //~| ERROR cannot borrow `_` as mutable more than once at a time
drop(a); drop(a);
let ref mut a @ ref mut b = 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
drop(b); drop(b);
let ref mut a @ ref mut b = 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
let ref mut a @ ref mut b = 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
//~| ERROR cannot borrow `_` as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time
*a = U; *a = U;
let ref mut a @ ref mut b = 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; *b = U;
let ref mut a @ ( 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 b,
[ [
ref mut c, ref mut c,
@ -50,7 +54,7 @@ fn main() {
) = (U, [U, U, U]); ) = (U, [U, U, U]);
let ref mut a @ ( 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 b,
[ [
ref mut c, ref mut c,
@ -60,37 +64,37 @@ fn main() {
) = (u(), [u(), u(), u()]); ) = (u(), [u(), u(), u()]);
let a @ (ref mut b, ref mut c) = (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 //~| ERROR borrow of moved value
let mut val = (U, [U, U]); let mut val = (U, [U, U]);
let a @ (b, [c, d]) = &mut val; // Same as ^-- 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 //~| ERROR borrow of moved value
let a @ &mut ref mut b = &mut U; 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 //~| ERROR borrow of moved value
let a @ &mut (ref mut b, ref mut c) = &mut (U, U); 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 //~| ERROR borrow of moved value
match Ok(U) { match Ok(U) {
ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
//~^ ERROR cannot borrow `a` as mutable more than once at a time //~^ ERROR cannot borrow value 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
} }
} }
match Ok(U) { match Ok(U) {
ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
//~^ ERROR cannot borrow `a` as mutable more than once at a time //~^ ERROR cannot borrow value 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
*b = U; *b = U;
} }
} }
match Ok(U) { match Ok(U) {
ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
//~^ ERROR cannot borrow `a` as mutable more than once at a time //~^ ERROR cannot borrow value 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 `_` 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 //~| ERROR cannot borrow `_` as mutable more than once at a time
*a = Err(U); *a = Err(U);
@ -101,8 +105,8 @@ fn main() {
} }
match Ok(U) { match Ok(U) {
ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
//~^ ERROR cannot borrow `a` as mutable more than once at a time //~^ ERROR cannot borrow value 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 `_` 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 //~| ERROR cannot borrow `_` as mutable more than once at a time
drop(a); drop(a);

View File

@ -1,226 +1,265 @@
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: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
--> $DIR/borrowck-pat-ref-mut-twice.rs:28:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:28:9
| |
LL | let ref mut a @ ref mut b = U; LL | let ref mut a @ ref mut b = U;
| ---------^^^--------- | ---------^^^---------
| | | | | |
| | another mutable borrow occurs here | | another mutable borrow, by `b`, occurs here
| first mutable borrow 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:31:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:32:9
| |
LL | let ref mut a @ ref mut b = U; LL | let ref mut a @ ref mut b = U;
| ---------^^^--------- | ---------^^^---------
| | | | | |
| | another mutable borrow occurs here | | another mutable borrow, by `b`, occurs here
| first mutable borrow 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:34:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:35:9
| |
LL | let ref mut a @ ref mut b = U; LL | let ref mut a @ ref mut b = U;
| ---------^^^--------- | ---------^^^---------
| | | | | |
| | another mutable borrow occurs here | | another mutable borrow, by `b`, occurs here
| first mutable borrow 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 --> $DIR/borrowck-pat-ref-mut-twice.rs:38:9
| |
LL | let ref mut a @ ref mut b = U; LL | let ref mut a @ ref mut b = U;
| ---------^^^--------- | ---------^^^---------
| | | | | |
| | another mutable borrow occurs here | | another mutable borrow, by `b`, occurs here
| first mutable borrow 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 --> $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 @ ( LL | let ref mut a @ (
| ^-------- | ^--------
| | | |
| _________first mutable borrow occurs here | _________first mutable borrow, by `a`, occurs here
| | | |
LL | | LL | |
LL | | ref mut b, LL | | ref mut b,
| | --------- another mutable borrow occurs here | | --------- another mutable borrow, by `b`, occurs here
LL | | [ LL | | [
LL | | ref mut c, LL | | ref mut c,
| | --------- another mutable borrow occurs here | | --------- another mutable borrow, by `c`, occurs here
LL | | ref mut d, LL | | ref mut d,
| | --------- another mutable borrow occurs here | | --------- another mutable borrow, by `d`, occurs here
LL | | ref e, LL | | ref e,
| | ----- also borrowed as immutable here | | ----- also borrowed as immutable, by `e`, here
LL | | ] LL | | ]
LL | | ) = (U, [U, U, U]); LL | | ) = (U, [U, U, 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
--> $DIR/borrowck-pat-ref-mut-twice.rs:52:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:56:9
| |
LL | let ref mut a @ ( LL | let ref mut a @ (
| ^-------- | ^--------
| | | |
| _________first mutable borrow occurs here | _________first mutable borrow, by `a`, occurs here
| | | |
LL | | LL | |
LL | | ref mut b, LL | | ref mut b,
| | --------- another mutable borrow occurs here | | --------- another mutable borrow, by `b`, occurs here
LL | | [ LL | | [
LL | | ref mut c, LL | | ref mut c,
| | --------- another mutable borrow occurs here | | --------- another mutable borrow, by `c`, occurs here
LL | | ref mut d, LL | | ref mut d,
| | --------- another mutable borrow occurs here | | --------- another mutable borrow, by `d`, occurs here
LL | | ref e, LL | | ref e,
| | ----- also borrowed as immutable here | | ----- also borrowed as immutable, by `e`, here
LL | | ] LL | | ]
LL | | ) = (u(), [u(), u(), u()]); LL | | ) = (u(), [u(), u(), u()]);
| |_________^ | |_________^
error[E0007]: cannot bind by-move with sub-bindings error: borrow of moved value
--> $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
--> $DIR/borrowck-pat-ref-mut-twice.rs:66:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:66:9
| |
LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- LL | let a @ (ref mut b, ref mut c) = (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 `(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 --> $DIR/borrowck-pat-ref-mut-twice.rs:70:9
| |
LL | let a @ &mut ref mut b = &mut U; LL | let a @ (b, [c, d]) = &mut val; // Same as ^--
| ^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it | -^^^^-^^^-^^-^^
| | | | |
| | | | 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 error: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-twice.rs:73:9 --> $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); 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 error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:78:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:82:9
| |
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^---------^ | ---------^^^^^^---------^
| | | | | |
| | another mutable borrow occurs here | | another mutable borrow, by `b`, occurs here
| first mutable borrow 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:78:37 --> $DIR/borrowck-pat-ref-mut-twice.rs:82:37
| |
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^^---------^ | ---------^^^^^^^---------^
| | | | | |
| | another mutable borrow occurs here | | another mutable borrow, by `b`, occurs here
| first mutable borrow 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:84:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:88:9
| |
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^---------^ | ---------^^^^^^---------^
| | | | | |
| | another mutable borrow occurs here | | another mutable borrow, by `b`, occurs here
| first mutable borrow 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:84:37 --> $DIR/borrowck-pat-ref-mut-twice.rs:88:37
| |
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^^---------^ | ---------^^^^^^^---------^
| | | | | |
| | another mutable borrow occurs here | | another mutable borrow, by `b`, occurs here
| first mutable borrow 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:91:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:95:9
| |
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^---------^ | ---------^^^^^^---------^
| | | | | |
| | another mutable borrow occurs here | | another mutable borrow, by `b`, occurs here
| first mutable borrow 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:91:37 --> $DIR/borrowck-pat-ref-mut-twice.rs:95:37
| |
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^^---------^ | ---------^^^^^^^---------^
| | | | | |
| | another mutable borrow occurs here | | another mutable borrow, by `b`, occurs here
| first mutable borrow 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:103:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:107:9
| |
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^---------^ | ---------^^^^^^---------^
| | | | | |
| | another mutable borrow occurs here | | another mutable borrow, by `b`, occurs here
| first mutable borrow 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:103:37 --> $DIR/borrowck-pat-ref-mut-twice.rs:107:37
| |
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^^---------^ | ---------^^^^^^^---------^
| | | | | |
| | another mutable borrow occurs here | | another mutable borrow, by `b`, occurs here
| first mutable borrow 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:10:11 --> $DIR/borrowck-pat-ref-mut-twice.rs:11:11
| |
LL | fn f1(ref mut a @ ref mut b: U) {} LL | fn f1(ref mut a @ ref mut b: U) {}
| ---------^^^--------- | ---------^^^---------
| | | | | |
| | another mutable borrow occurs here | | another mutable borrow, by `b`, occurs here
| first mutable borrow 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:12:11 --> $DIR/borrowck-pat-ref-mut-twice.rs:13:11
| |
LL | fn f2(ref mut a @ ref mut b: U) {} LL | fn f2(ref mut a @ ref mut b: U) {}
| ---------^^^--------- | ---------^^^---------
| | | | | |
| | another mutable borrow occurs here | | another mutable borrow, by `b`, occurs here
| first mutable borrow 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:15:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:16:9
| |
LL | ref mut a @ [ LL | ref mut a @ [
| ^-------- | ^--------
| | | |
| _________first mutable borrow occurs here | _________first mutable borrow, by `a`, occurs here
| | | |
LL | | LL | |
LL | | [ref b @ .., _], LL | | [ref b @ .., _],
| | ---------- also borrowed as immutable here | | ---------- also borrowed as immutable, by `b`, here
LL | | [_, ref mut mid @ ..], LL | | [_, ref mut mid @ ..],
| | ---------------- another mutable borrow occurs here | | ---------------- another mutable borrow, by `mid`, occurs here
LL | | .., LL | | ..,
LL | | [..], LL | | [..],
LL | | ] : [[U; 4]; 5] 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 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; LL | let ref mut a @ ref mut b = U;
| ------------^^^^^^^^^ | ------------^^^^^^^^^
@ -232,7 +271,7 @@ LL | drop(a);
| - first borrow later used here | - first borrow later used here
error[E0499]: cannot borrow `_` as mutable more than once at a time 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; LL | let ref mut a @ ref mut b = U;
| ------------^^^^^^^^^ | ------------^^^^^^^^^
@ -244,7 +283,7 @@ LL | *a = U;
| ------ first borrow later used here | ------ first borrow later used here
error[E0382]: borrow of moved value 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); 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 | ----------------^^^^^^^^^- ------ 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 | value moved here
error[E0382]: borrow of moved value 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 ^-- 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 | ------------^-- -------- 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 | value moved here
error[E0382]: borrow of moved value 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; 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 | ---------^^^^^^^^^ ------ 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 | value moved here
error[E0382]: borrow of moved value 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); 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 | ---------------------^^^^^^^^^- ----------- 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 | value moved here
error[E0499]: cannot borrow `_` as mutable more than once at a time 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) => { 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 | ----------- first borrow later used here
error[E0499]: cannot borrow `_` as mutable more than once at a time 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) => { 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 | ----------- first borrow later used here
error[E0499]: cannot borrow `_` as mutable more than once at a time 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) => { 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 | - first borrow later used here
error[E0499]: cannot borrow `_` as mutable more than once at a time 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) => { 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); LL | drop(a);
| - first borrow later used here | - 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. Some errors have detailed explanations: E0382, E0499.
For more information about an error, try `rustc --explain E0007`. 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. // Test that mixing `Copy` and non-`Copy` types in `@` patterns is forbidden.
#![feature(bindings_after_at)] #![feature(bindings_after_at)]
#![feature(move_ref_pattern)]
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
struct C; struct C;
@ -9,12 +10,9 @@ struct NC<A, B>(A, B);
fn main() { fn main() {
let a @ NC(b, c) = NC(C, C); 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)); 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 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 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); 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 | ----------^- -------- 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 = 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 this error, try `rustc --explain E0382`.
For more information about an error, try `rustc --explain E0007`.

View File

@ -8,6 +8,7 @@
// this would create problems for the generalization aforementioned. // this would create problems for the generalization aforementioned.
#![feature(bindings_after_at)] #![feature(bindings_after_at)]
#![feature(move_ref_pattern)]
fn main() { fn main() {
struct NotCopy; struct NotCopy;
@ -24,14 +25,26 @@ fn main() {
let ref a @ b = &NotCopy; // OK let ref a @ b = &NotCopy; // OK
let _: &&NotCopy = a; let _: &&NotCopy = a;
let ref 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 ref mut a @ b = NotCopy; //~ ERROR cannot bind by-move and by-ref in the same pattern 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) { match Ok(NotCopy) {
Ok(ref a @ b) | Err(ref a @ b) => {} Ok(ref a @ b) | Err(b @ ref a) => {
//~^ ERROR cannot bind by-move and by-ref in the same pattern //~^ 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 { match NotCopy {
ref a @ b => {} ref a @ b => {
//~^ ERROR cannot bind by-move and by-ref in the same pattern //~^ 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 error: cannot move out of value because it is borrowed
--> $DIR/default-binding-modes-both-sides-independent.rs:27:17 --> $DIR/default-binding-modes-both-sides-independent.rs:28:9
| |
LL | let ref a @ b = NotCopy; LL | let ref a @ b = NotCopy;
| --------^ | -----^^^-
| | | | | |
| | by-move pattern here | | value moved into `b` here
| by-ref pattern here | value borrowed, by `a`, here
error[E0009]: cannot bind by-move and by-ref in the same pattern error: cannot move out of value because it is borrowed
--> $DIR/default-binding-modes-both-sides-independent.rs:28:21 --> $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; LL | let ref mut a @ b = NotCopy;
| ------------^ | ------------^
| | | | | |
| | by-move pattern here | | move out of value occurs here
| by-ref pattern 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 error: aborting due to 6 previous errors
--> $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[E0009]: cannot bind by-move and by-ref in the same pattern For more information about this error, try `rustc --explain E0505`.
--> $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`.

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 { enum E {
Foo(String, String, String), Foo(String, String, String),
} }
@ -11,10 +15,8 @@ fn main() {
let bar = Bar { a: "1".to_string(), b: "2".to_string() }; let bar = Bar { a: "1".to_string(), b: "2".to_string() };
match E::Foo("".into(), "".into(), "".into()) { match E::Foo("".into(), "".into(), "".into()) {
E::Foo(a, b, ref c) => {} E::Foo(a, b, ref c) => {}
//~^ ERROR cannot bind by-move and by-ref in the same pattern
} }
match bar { match bar {
Bar {a, ref b} => {} Bar { a, ref b } => {}
//~^ ERROR cannot bind by-move and by-ref in the same pattern
} }
} }

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

View File

@ -1,10 +1,11 @@
#![feature(move_ref_pattern)]
struct Foo {} struct Foo {}
pub fn main() { pub fn main() {
let mut tups = vec![(Foo{}, Foo{})]; let mut tups = vec![(Foo {}, Foo {})];
// The below desugars to &(ref n, mut m). // The below desugars to &(ref n, mut m).
for (n, mut m) in &tups { 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 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 { LL | for (n, mut m) in &tups {
| ----- ^^^^^ | ----- ^^^^^
@ -15,7 +7,6 @@ LL | for (n, mut m) in &tups {
| data moved here | data moved here
| move occurs because `m` has type `Foo`, which does not implement the `Copy` trait | 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 this error, try `rustc --explain E0507`.
For more information about an error, try `rustc --explain E0009`.