From 7af9ff3e699207da7a5220b98ba9831d66697c80 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 19 Jan 2020 02:14:51 +0100 Subject: [PATCH 1/6] introduce `#![feature(move_ref_pattern)]` --- src/librustc_errors/diagnostic_builder.rs | 16 +- src/librustc_feature/active.rs | 4 + .../hair/pattern/check_match.rs | 177 +++++++++++------- src/librustc_span/symbol.rs | 1 + 4 files changed, 125 insertions(+), 73 deletions(-) diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index 3c217c1d64373..82bbae18a9c0b 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -186,11 +186,25 @@ impl<'a> DiagnosticBuilder<'a> { /// all, and you just supplied a `Span` to create the diagnostic, /// then the snippet will just include that `Span`, which is /// called the primary span. - pub fn span_label>(&mut self, span: Span, label: T) -> &mut Self { + pub fn span_label(&mut self, span: Span, label: impl Into) -> &mut Self { self.0.diagnostic.span_label(span, label); self } + /// Labels all the given spans with the provided label. + /// See `span_label` for more information. + pub fn span_labels( + &mut self, + spans: impl IntoIterator, + label: impl AsRef, + ) -> &mut Self { + let label = label.as_ref(); + for span in spans { + self.0.diagnostic.span_label(span, label); + } + self + } + forward!(pub fn note_expected_found( &mut self, expected_label: &dyn fmt::Display, diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index f20a57ea61c42..e0abf5d4f3c1f 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -538,6 +538,10 @@ declare_features! ( /// For example, you can write `x @ Some(y)`. (active, bindings_after_at, "1.41.0", Some(65490), None), + /// Allows patterns with concurrent by-move and by-ref bindings. + /// For example, you can write `Foo(a, ref b)` where `a` is by-move and `b` is by-ref. + (active, move_ref_pattern, "1.42.0", Some(68354), None), + /// Allows `impl const Trait for T` syntax. (active, const_trait_impl, "1.42.0", Some(67792), None), diff --git a/src/librustc_mir_build/hair/pattern/check_match.rs b/src/librustc_mir_build/hair/pattern/check_match.rs index 82822f0c471a4..a563864b61b31 100644 --- a/src/librustc_mir_build/hair/pattern/check_match.rs +++ b/src/librustc_mir_build/hair/pattern/check_match.rs @@ -16,8 +16,7 @@ use rustc_session::lint::builtin::BINDINGS_WITH_VARIANT_NAME; use rustc_session::lint::builtin::{IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS}; use rustc_session::parse::feature_err; use rustc_session::Session; -use rustc_span::symbol::sym; -use rustc_span::{MultiSpan, Span}; +use rustc_span::{sym, Span}; use syntax::ast::Mutability; use std::slice; @@ -114,8 +113,10 @@ impl PatCtxt<'_, '_> { impl<'tcx> MatchVisitor<'_, 'tcx> { fn check_patterns(&mut self, has_guard: bool, pat: &Pat<'_>) { - check_legality_of_move_bindings(self, has_guard, pat); - check_borrow_conflicts_in_at_patterns(self, pat); + if !self.tcx.features().move_ref_pattern { + check_legality_of_move_bindings(self, has_guard, pat); + } + pat.walk_always(|pat| check_borrow_conflicts_in_at_patterns(self, pat)); if !self.tcx.features().bindings_after_at { check_legality_of_bindings_in_at_patterns(self, pat); } @@ -559,6 +560,11 @@ fn maybe_point_at_variant(ty: Ty<'_>, patterns: &[super::Pat<'_>]) -> Vec covered } +/// Check if a by-value binding is by-value. That is, check if the binding's type is not `Copy`. +fn is_binding_by_move(cx: &MatchVisitor<'_, '_>, hir_id: HirId, span: Span) -> bool { + !cx.tables.node_type(hir_id).is_copy_modulo_regions(cx.tcx, cx.param_env, span) +} + /// Check the legality of legality of by-move bindings. fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: bool, pat: &Pat<'_>) { let sess = cx.tcx.sess; @@ -589,8 +595,7 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo pat.walk_always(|p| { if let hir::PatKind::Binding(.., sub) = &p.kind { if let Some(ty::BindByValue(_)) = tables.extract_binding_mode(sess, p.hir_id, p.span) { - let pat_ty = tables.node_type(p.hir_id); - if !pat_ty.is_copy_modulo_regions(cx.tcx, cx.param_env, pat.span) { + if is_binding_by_move(cx, p.hir_id, p.span) { check_move(p, sub.as_deref()); } } @@ -599,11 +604,11 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo // Found some bad by-move spans, error! if !by_move_spans.is_empty() { - let mut err = struct_span_err!( - sess, - MultiSpan::from_spans(by_move_spans.clone()), - E0009, - "cannot bind by-move and by-ref in the same pattern", + let mut err = feature_err( + &sess.parse_sess, + sym::move_ref_pattern, + by_move_spans.clone(), + "binding by-move and by-ref in the same pattern is unstable", ); for span in by_ref_spans.iter() { err.span_label(*span, "by-ref pattern here"); @@ -615,81 +620,109 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo } } -/// Check that there are no borrow conflicts in `binding @ subpat` patterns. +/// Check that there are no borrow or move conflicts in `binding @ subpat` patterns. /// /// For example, this would reject: /// - `ref x @ Some(ref mut y)`, -/// - `ref mut x @ Some(ref y)` -/// - `ref mut x @ Some(ref mut y)`. +/// - `ref mut x @ Some(ref y)`, +/// - `ref mut x @ Some(ref mut y)`, +/// - `ref mut? x @ Some(y)`, and +/// - `x @ Some(ref mut? y)`. /// /// This analysis is *not* subsumed by NLL. fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat<'_>) { - let tab = cx.tables; - let sess = cx.tcx.sess; - // Get the mutability of `p` if it's by-ref. - let extract_binding_mut = |hir_id, span| match tab.extract_binding_mode(sess, hir_id, span)? { - ty::BindByValue(_) => None, - ty::BindByReference(m) => Some(m), + // Extract `sub` in `binding @ sub`. + let (name, sub) = match &pat.kind { + hir::PatKind::Binding(.., name, Some(sub)) => (*name, sub), + _ => return, }; - pat.walk_always(|pat| { - // Extract `sub` in `binding @ sub`. - let (name, sub) = match &pat.kind { - hir::PatKind::Binding(.., name, Some(sub)) => (*name, sub), - _ => return, - }; + let binding_span = pat.span.with_hi(name.span.hi()); - // Extract the mutability. - let mut_outer = match extract_binding_mut(pat.hir_id, pat.span) { - None => return, - Some(m) => m, - }; + let tables = cx.tables; + let sess = cx.tcx.sess; - // We now have `ref $mut_outer binding @ sub` (semantically). - // Recurse into each binding in `sub` and find mutability conflicts. - let mut conflicts_mut_mut = Vec::new(); - let mut conflicts_mut_ref = Vec::new(); - sub.each_binding(|_, hir_id, span, _| { - if let Some(mut_inner) = extract_binding_mut(hir_id, span) { - match (mut_outer, mut_inner) { - (Mutability::Not, Mutability::Not) => {} - (Mutability::Mut, Mutability::Mut) => conflicts_mut_mut.push(span), - _ => conflicts_mut_ref.push(span), + // Get the binding move, extract the mutability if by-ref. + let mut_outer = match tables.extract_binding_mode(sess, pat.hir_id, pat.span) { + Some(ty::BindByValue(_)) if is_binding_by_move(cx, pat.hir_id, pat.span) => { + // We have `x @ pat` where `x` is by-move. Reject all borrows in `pat`. + let mut conflicts_ref = Vec::new(); + sub.each_binding(|_, hir_id, span, _| { + match tables.extract_binding_mode(sess, hir_id, span) { + Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id, span) => { + sess.delay_span_bug(span, "by-move in subpat unchecked by borrowck"); + } + Some(ty::BindByValue(_)) | None => {} + Some(ty::BindByReference(_)) => conflicts_ref.push(span), } + }); + if !conflicts_ref.is_empty() { + let occurs_because = format!( + "move occurs because `{}` has type `{}` which does implement the `Copy` trait", + name, + tables.node_type(pat.hir_id), + ); + sess.struct_span_err(pat.span, &format!("borrow of moved value: `{}`", name)) + .span_label(binding_span, "value moved here") + .span_label(binding_span, occurs_because) + .span_labels(conflicts_ref, "value borrowed here after move") + .emit(); } - }); + return; + } + Some(ty::BindByValue(_)) | None => return, + Some(ty::BindByReference(m)) => m, + }; - // Report errors if any. - let binding_span = pat.span.with_hi(name.span.hi()); - if !conflicts_mut_mut.is_empty() { - // Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`. - let msg = &format!("cannot borrow `{}` as mutable more than once at a time", name); - let mut err = sess.struct_span_err(pat.span, msg); - err.span_label(binding_span, "first mutable borrow occurs here"); - for sp in conflicts_mut_mut { - err.span_label(sp, "another mutable borrow occurs here"); - } - for sp in conflicts_mut_ref { - err.span_label(sp, "also borrowed as immutable here"); - } - err.emit(); - } else if !conflicts_mut_ref.is_empty() { - // Report mutability conflicts for e.g. `ref x @ Some(ref mut y)` or the converse. - let (primary, also) = match mut_outer { - Mutability::Mut => ("mutable", "immutable"), - Mutability::Not => ("immutable", "mutable"), - }; - let msg = &format!( - "cannot borrow `{}` as {} because it is also borrowed as {}", - name, also, primary, - ); - let mut err = sess.struct_span_err(pat.span, msg); - err.span_label(binding_span, &format!("{} borrow occurs here", primary)); - for sp in conflicts_mut_ref { - err.span_label(sp, &format!("{} borrow occurs here", also)); - } - err.emit(); + // We now have `ref $mut_outer binding @ sub` (semantically). + // Recurse into each binding in `sub` and find mutability or move conflicts. + let mut conflicts_move = Vec::new(); + let mut conflicts_mut_mut = Vec::new(); + let mut conflicts_mut_ref = Vec::new(); + sub.each_binding(|_, hir_id, span, _| match tables.extract_binding_mode(sess, hir_id, span) { + Some(ty::BindByReference(mut_inner)) => match (mut_outer, mut_inner) { + (Mutability::Not, Mutability::Not) => {} // Both sides are `ref`. + (Mutability::Mut, Mutability::Mut) => conflicts_mut_mut.push(span), // 2x `ref mut`. + _ => conflicts_mut_ref.push(span), // `ref` + `ref mut` in either direction. + }, + Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id, span) => { + conflicts_move.push(span) // `ref mut?` + by-move conflict. } + Some(ty::BindByValue(_)) | None => {} // `ref mut?` + by-copy is fine. }); + + // Report errors if any. + if !conflicts_mut_mut.is_empty() { + // Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`. + let msg = &format!("cannot borrow `{}` as mutable more than once at a time", name); + sess.struct_span_err(pat.span, msg) + .span_label(binding_span, "first mutable borrow occurs here") + .span_labels(conflicts_mut_mut, "another mutable borrow occurs here") + .span_labels(conflicts_mut_ref, "also borrowed as immutable here") + .span_labels(conflicts_move, "also moved here") + .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, + ); + sess.struct_span_err(pat.span, msg) + .span_label(binding_span, format!("{} borrow occurs here", primary)) + .span_labels(conflicts_mut_ref, format!("{} borrow occurs here", also)) + .span_labels(conflicts_move, "also moved here") + .emit(); + } else if !conflicts_move.is_empty() { + // Report by-ref and by-move conflicts, e.g. `ref x @ y`. + let msg = &format!("cannot move out of `{}` because it is borrowed", name); + sess.struct_span_err(pat.span, msg) + .span_label(binding_span, format!("borrow of `{}` occurs here", name)) + .span_labels(conflicts_move, format!("move out of `{}` occurs here", name)) + .emit(); + } } /// Forbids bindings in `@` patterns. This used to be is necessary for memory safety, diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index e4f8b5a014389..a8cd027831d31 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -455,6 +455,7 @@ symbols! { module, module_path, more_struct_aliases, + move_ref_pattern, move_val_init, movbe_target_feature, mul_with_overflow, From d984f127f662f7a1fcf0472230a1b64fcc3325d5 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 19 Jan 2020 02:47:01 +0100 Subject: [PATCH 2/6] move_ref_patterns: introduce tests bindings_after_at: harden tests --- ...her-can-live-while-the-other-survives-2.rs | 15 - ...can-live-while-the-other-survives-2.stderr | 11 - ...her-can-live-while-the-other-survives-3.rs | 18 - ...can-live-while-the-other-survives-3.stderr | 11 - ...her-can-live-while-the-other-survives-4.rs | 15 - ...can-live-while-the-other-survives-4.stderr | 11 - src/test/ui/drop/dynamic-drop-async.rs | 10 + src/test/ui/drop/dynamic-drop.rs | 8 + src/test/ui/error-codes/E0009.rs | 9 - src/test/ui/error-codes/E0009.stderr | 11 - src/test/ui/issues/issue-53840.stderr | 20 - src/test/ui/moves/move-out-of-slice-2.rs | 2 +- ...her-can-live-while-the-other-survives-1.rs | 23 +- ...can-live-while-the-other-survives-1.stderr | 59 +- .../bind-by-move-no-subbindings-fun-param.rs | 4 +- ...nd-by-move-no-subbindings-fun-param.stderr | 13 +- .../borrowck-move-and-move.rs | 36 +- .../borrowck-move-and-move.stderr | 69 +-- .../borrowck-pat-at-and-box-pass.rs | 11 + .../borrowck-pat-at-and-box.rs | 41 +- .../borrowck-pat-at-and-box.stderr | 109 ++-- ...k-pat-by-move-and-ref-inverse-promotion.rs | 10 + ...t-by-move-and-ref-inverse-promotion.stderr | 12 + .../borrowck-pat-by-move-and-ref-inverse.rs | 98 ++++ ...orrowck-pat-by-move-and-ref-inverse.stderr | 503 ++++++++++++++++++ .../borrowck-pat-by-move-and-ref.rs | 73 ++- .../borrowck-pat-by-move-and-ref.stderr | 243 ++++++++- .../borrowck-pat-ref-mut-and-ref.rs | 4 + .../borrowck-pat-ref-mut-and-ref.stderr | 111 ++-- .../borrowck-pat-ref-mut-twice.rs | 12 +- .../borrowck-pat-ref-mut-twice.stderr | 125 +++-- .../bindings-after-at/copy-and-move-mixed.rs | 8 +- .../copy-and-move-mixed.stderr | 25 +- ...lt-binding-modes-both-sides-independent.rs | 25 +- ...inding-modes-both-sides-independent.stderr | 74 ++- .../borrowck-move-ref-pattern-pass.rs | 31 ++ .../borrowck-move-ref-pattern.rs | 50 ++ .../borrowck-move-ref-pattern.stderr | 208 ++++++++ .../feature-gate-move_ref_pattern.rs | 23 + .../feature-gate-move_ref_pattern.stderr | 66 +++ .../move-ref-patterns}/issue-53840.rs | 8 +- ...move-ref-patterns-closure-captures-pass.rs | 30 ++ .../move-ref-patterns-closure-captures.rs | 34 ++ .../move-ref-patterns-closure-captures.stderr | 39 ++ ...move-ref-patterns-default-binding-modes.rs | 16 + ...-ref-patterns-default-binding-modes.stderr | 21 + .../move-ref-patterns-dynamic-semantics.rs | 81 +++ .../pattern/rest-pat-semantic-disallowed.rs | 2 +- .../ui/rfc-2005-default-binding-mode/for.rs | 7 +- .../rfc-2005-default-binding-mode/for.stderr | 15 +- 50 files changed, 1919 insertions(+), 541 deletions(-) delete mode 100644 src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.rs delete mode 100644 src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.stderr delete mode 100644 src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.rs delete mode 100644 src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.stderr delete mode 100644 src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.rs delete mode 100644 src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.stderr delete mode 100644 src/test/ui/error-codes/E0009.rs delete mode 100644 src/test/ui/error-codes/E0009.stderr delete mode 100644 src/test/ui/issues/issue-53840.stderr create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr create mode 100644 src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs create mode 100644 src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.rs create mode 100644 src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr create mode 100644 src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.rs create mode 100644 src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.stderr rename src/test/ui/{issues => pattern/move-ref-patterns}/issue-53840.rs (64%) create mode 100644 src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs create mode 100644 src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.rs create mode 100644 src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr create mode 100644 src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.rs create mode 100644 src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.stderr create mode 100644 src/test/ui/pattern/move-ref-patterns/move-ref-patterns-dynamic-semantics.rs diff --git a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.rs b/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.rs deleted file mode 100644 index 238f2d958c625..0000000000000 --- a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.rs +++ /dev/null @@ -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!() - } -} diff --git a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.stderr b/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.stderr deleted file mode 100644 index ff00aa8caa8d3..0000000000000 --- a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.stderr +++ /dev/null @@ -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`. diff --git a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.rs b/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.rs deleted file mode 100644 index e8357e9178819..0000000000000 --- a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.rs +++ /dev/null @@ -1,18 +0,0 @@ -struct X { x: (), } - -impl Drop for X { - fn drop(&mut self) { - println!("destructor runs"); - } -} - -enum DoubleOption { 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!() - } -} diff --git a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.stderr b/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.stderr deleted file mode 100644 index 3e8358da3507d..0000000000000 --- a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.stderr +++ /dev/null @@ -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`. diff --git a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.rs b/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.rs deleted file mode 100644 index 41dafd2b5bf72..0000000000000 --- a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.rs +++ /dev/null @@ -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!() - } -} diff --git a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.stderr b/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.stderr deleted file mode 100644 index 00e0c70d6494b..0000000000000 --- a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.stderr +++ /dev/null @@ -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`. diff --git a/src/test/ui/drop/dynamic-drop-async.rs b/src/test/ui/drop/dynamic-drop-async.rs index 30a8960594493..88d36ab6aa664 100644 --- a/src/test/ui/drop/dynamic-drop-async.rs +++ b/src/test/ui/drop/dynamic-drop-async.rs @@ -7,6 +7,8 @@ // edition:2018 // ignore-wasm32-bare compiled with panic=abort by default +#![feature(move_ref_pattern)] + #![allow(unused)] use std::{ @@ -227,6 +229,12 @@ async fn subslice_pattern_reassign(a: Rc) { a.alloc().await; } +async fn move_ref_pattern(a: Rc) { + 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(cx: &mut Context<'_>, ref f: F) where F: Fn(Rc) -> G, @@ -322,4 +330,6 @@ fn main() { run_test(context, |a| subslice_pattern_from_end_with_drop(a, false, true)); run_test(context, |a| subslice_pattern_from_end_with_drop(a, false, false)); run_test(context, |a| subslice_pattern_reassign(a)); + + run_test(context, |a| move_ref_pattern(a)); } diff --git a/src/test/ui/drop/dynamic-drop.rs b/src/test/ui/drop/dynamic-drop.rs index b4406204a5db9..208a743ed1815 100644 --- a/src/test/ui/drop/dynamic-drop.rs +++ b/src/test/ui/drop/dynamic-drop.rs @@ -2,6 +2,7 @@ // ignore-wasm32-bare compiled with panic=abort by default #![feature(generators, generator_trait, untagged_unions)] +#![feature(move_ref_pattern)] #![allow(unused_assignments)] #![allow(unused_variables)] @@ -290,6 +291,11 @@ fn subslice_mixed_min_lengths(a: &Allocator, c: i32) { } } +fn move_ref_pattern(a: &Allocator) { + let mut tup = (a.alloc(), a.alloc(), a.alloc(), a.alloc()); + let (ref _a, ref mut _b, _c, mut _d) = tup; +} + fn panic_after_return(a: &Allocator) -> Ptr<'_> { // Panic in the drop of `p` or `q` can leak let exceptions = vec![8, 9]; @@ -453,6 +459,8 @@ fn main() { run_test(|a| subslice_mixed_min_lengths(a, 6)); run_test(|a| subslice_mixed_min_lengths(a, 7)); + run_test(|a| move_ref_pattern(a)); + run_test(|a| { panic_after_return(a); }); diff --git a/src/test/ui/error-codes/E0009.rs b/src/test/ui/error-codes/E0009.rs deleted file mode 100644 index 0610d03cfe96d..0000000000000 --- a/src/test/ui/error-codes/E0009.rs +++ /dev/null @@ -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!() - } -} diff --git a/src/test/ui/error-codes/E0009.stderr b/src/test/ui/error-codes/E0009.stderr deleted file mode 100644 index 446a436d64779..0000000000000 --- a/src/test/ui/error-codes/E0009.stderr +++ /dev/null @@ -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`. diff --git a/src/test/ui/issues/issue-53840.stderr b/src/test/ui/issues/issue-53840.stderr deleted file mode 100644 index 9cb034e7592da..0000000000000 --- a/src/test/ui/issues/issue-53840.stderr +++ /dev/null @@ -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`. diff --git a/src/test/ui/moves/move-out-of-slice-2.rs b/src/test/ui/moves/move-out-of-slice-2.rs index e460246193e5b..5c1a61eb375a4 100644 --- a/src/test/ui/moves/move-out-of-slice-2.rs +++ b/src/test/ui/moves/move-out-of-slice-2.rs @@ -1,4 +1,4 @@ -#![feature(slice_patterns, unsized_locals)] +#![feature(unsized_locals)] struct A; #[derive(Clone, Copy)] diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs index 75d7af58e706d..1cad822382677 100644 --- a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs @@ -3,33 +3,38 @@ // where one side is by-ref and the other is by-move. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] -struct X { x: () } +struct X { + x: (), +} fn main() { let x = Some(X { x: () }); match x { - Some(ref _y @ _z) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern - None => panic!() + Some(ref _y @ _z) => {} //~ ERROR cannot move out of `_y` because it is borrowed + None => panic!(), } let x = Some(X { x: () }); match x { - Some(_z @ ref _y) => { }, //~ ERROR cannot bind by-move with sub-bindings + Some(_z @ ref _y) => {} //~^ ERROR borrow of moved value - None => panic!() + //~| ERROR borrow of moved value + None => panic!(), } let mut x = Some(X { x: () }); match x { - Some(ref mut _y @ _z) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern - None => panic!() + Some(ref mut _y @ _z) => {} //~ ERROR cannot move out of `_y` because it is borrowed + None => panic!(), } let mut x = Some(X { x: () }); match x { - Some(_z @ ref mut _y) => { }, //~ ERROR cannot bind by-move with sub-bindings + Some(_z @ ref mut _y) => {} //~^ ERROR borrow of moved value - None => panic!() + //~| ERROR borrow of moved value + None => panic!(), } } diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr index 22d62ff4f003f..6ad0248fc6b2f 100644 --- a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr @@ -1,37 +1,45 @@ -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:12:23 +error: cannot move out of `_y` because it is borrowed + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:15:14 | -LL | Some(ref _y @ _z) => { }, - | ---------^^ +LL | Some(ref _y @ _z) => {} + | ------^^^-- | | | - | | by-move pattern here - | by-ref pattern here + | | move out of `_y` occurs here + | borrow of `_y` occurs here -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:18:14 +error: borrow of moved value: `_z` + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:21:14 | -LL | Some(_z @ ref _y) => { }, - | ^^^^^^^^^^^ binds an already bound by-move value by moving it +LL | Some(_z @ ref _y) => {} + | --^^^------ + | | | + | | value borrowed here after move + | value moved here + | move occurs because `_z` has type `X` which does implement the `Copy` trait -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:25:27 +error: cannot move out of `_y` because it is borrowed + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:29:14 | -LL | Some(ref mut _y @ _z) => { }, - | -------------^^ +LL | Some(ref mut _y @ _z) => {} + | ----------^^^-- | | | - | | by-move pattern here - | by-ref pattern here + | | move out of `_y` occurs here + | borrow of `_y` occurs here -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:31:14 +error: borrow of moved value: `_z` + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:35:14 | -LL | Some(_z @ ref mut _y) => { }, - | ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it +LL | Some(_z @ ref mut _y) => {} + | --^^^---------- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `_z` has type `X` which does implement the `Copy` trait error[E0382]: borrow of moved value - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:18:19 + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:21:19 | -LL | Some(_z @ ref _y) => { }, +LL | Some(_z @ ref _y) => {} | -----^^^^^^ | | | | | value borrowed here after move @@ -40,9 +48,9 @@ LL | Some(_z @ ref _y) => { }, = note: move occurs because value has type `X`, which does not implement the `Copy` trait error[E0382]: borrow of moved value - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:31:19 + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:35:19 | -LL | Some(_z @ ref mut _y) => { }, +LL | Some(_z @ ref mut _y) => {} | -----^^^^^^^^^^ | | | | | value borrowed here after move @@ -52,5 +60,4 @@ LL | Some(_z @ ref mut _y) => { }, error: aborting due to 6 previous errors -Some errors have detailed explanations: E0007, E0009, E0382. -For more information about an error, try `rustc --explain E0007`. +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs index 86fb04e2edf5b..7a2e5128b8537 100644 --- a/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs @@ -1,14 +1,14 @@ // See issue #12534. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] fn main() {} struct A(Box); fn f(a @ A(u): A) -> Box { - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + //~^ ERROR use of moved value drop(a); u } diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr index b039708fd3e0a..cfd978e132709 100644 --- a/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr @@ -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 { - | ^^^^^^^^ binds an already bound by-move value by moving it - error[E0382]: use of moved value - --> $DIR/bind-by-move-no-subbindings-fun-param.rs:9:12 + --> $DIR/bind-by-move-no-subbindings-fun-param.rs:10:12 | LL | fn f(a @ A(u): A) -> Box { | ------^- @@ -14,7 +8,6 @@ LL | fn f(a @ A(u): A) -> Box { | value moved here | move occurs because value has type `A`, which does not implement the `Copy` trait -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0007, E0382. -For more information about an error, try `rustc --explain E0007`. +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs index 2cd375da9a56f..10865b92393b6 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs @@ -1,46 +1,34 @@ // Test that moving on both sides of an `@` pattern is not allowed. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] fn main() { struct U; // Not copy! // Prevent promotion: - fn u() -> U { U } + fn u() -> U { + U + } - let a @ b = U; - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + let a @ b = U; //~ ERROR use of moved value - let a @ (b, c) = (U, U); - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + let a @ (b, c) = (U, U); //~ ERROR use of moved value - let a @ (b, c) = (u(), u()); - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + let a @ (b, c) = (u(), u()); //~ ERROR use of moved value match Ok(U) { - a @ Ok(b) | a @ Err(b) => {} - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value - //~| ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + a @ Ok(b) | a @ Err(b) => {} //~ ERROR use of moved value + //~^ ERROR use of moved value } - fn fun(a @ b: U) {} - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + fn fun(a @ b: U) {} //~ ERROR use of moved value match [u(), u(), u(), u()] { - xs @ [a, .., b] => {} - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + xs @ [a, .., b] => {} //~ ERROR use of moved value } match [u(), u(), u(), u()] { - xs @ [_, ys @ .., _] => {} - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + xs @ [_, ys @ .., _] => {} //~ ERROR use of moved value } } diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr index 12ebcb72af11c..56613ee7618b4 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr @@ -1,53 +1,5 @@ -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:11:9 - | -LL | let a @ b = U; - | ^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:15:9 - | -LL | let a @ (b, c) = (U, U); - | ^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:19:9 - | -LL | let a @ (b, c) = (u(), u()); - | ^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:24:9 - | -LL | a @ Ok(b) | a @ Err(b) => {} - | ^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:24:21 - | -LL | a @ Ok(b) | a @ Err(b) => {} - | ^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:36:9 - | -LL | xs @ [a, .., b] => {} - | ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:42:9 - | -LL | xs @ [_, ys @ .., _] => {} - | ^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:31:12 - | -LL | fn fun(a @ b: U) {} - | ^^^^^ binds an already bound by-move value by moving it - error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:11:13 + --> $DIR/borrowck-move-and-move.rs:14:13 | LL | let a @ b = U; | ----^ - move occurs because value has type `main::U`, which does not implement the `Copy` trait @@ -56,7 +8,7 @@ LL | let a @ b = U; | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:15:17 + --> $DIR/borrowck-move-and-move.rs:16:17 | LL | let a @ (b, c) = (U, U); | --------^- ------ move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait @@ -65,7 +17,7 @@ LL | let a @ (b, c) = (U, U); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:19:17 + --> $DIR/borrowck-move-and-move.rs:18:17 | LL | let a @ (b, c) = (u(), u()); | --------^- ---------- move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait @@ -74,7 +26,7 @@ LL | let a @ (b, c) = (u(), u()); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:24:16 + --> $DIR/borrowck-move-and-move.rs:21:16 | LL | match Ok(U) { | ----- move occurs because value has type `std::result::Result`, which does not implement the `Copy` trait @@ -85,7 +37,7 @@ LL | a @ Ok(b) | a @ Err(b) => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:24:29 + --> $DIR/borrowck-move-and-move.rs:21:29 | LL | match Ok(U) { | ----- move occurs because value has type `std::result::Result`, which does not implement the `Copy` trait @@ -96,7 +48,7 @@ LL | a @ Ok(b) | a @ Err(b) => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:36:22 + --> $DIR/borrowck-move-and-move.rs:28:22 | LL | match [u(), u(), u(), u()] { | -------------------- move occurs because value has type `[main::U; 4]`, which does not implement the `Copy` trait @@ -107,7 +59,7 @@ LL | xs @ [a, .., b] => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:42:18 + --> $DIR/borrowck-move-and-move.rs:32:18 | LL | match [u(), u(), u(), u()] { | -------------------- move occurs because value has type `[main::U; 4]`, which does not implement the `Copy` trait @@ -118,7 +70,7 @@ LL | xs @ [_, ys @ .., _] => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:31:16 + --> $DIR/borrowck-move-and-move.rs:25:16 | LL | fn fun(a @ b: U) {} | ----^ @@ -127,7 +79,6 @@ LL | fn fun(a @ b: U) {} | value moved here | move occurs because value has type `main::U`, which does not implement the `Copy` trait -error: aborting due to 16 previous errors +error: aborting due to 8 previous errors -Some errors have detailed explanations: E0007, E0382. -For more information about an error, try `rustc --explain E0007`. +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs index 092bd1133dd62..271f4bca0fcb8 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs @@ -3,6 +3,7 @@ // Test `@` patterns combined with `box` patterns. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] #![feature(box_patterns)] #[derive(Copy, Clone)] @@ -72,4 +73,14 @@ fn main() { } _ => {} } + + match Box::new([Ok(c()), Err(nc()), Ok(c())]) { + box [Ok(a), ref xs @ .., Err(b)] => {} + _ => {} + } + + match [Ok(Box::new(c())), Err(Box::new(nc())), Ok(Box::new(c())), Ok(Box::new(c()))] { + [Ok(box ref a), ref xs @ .., Err(box b), Err(box ref mut c)] => {} + _ => {} + } } diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs index 3b2f598dc0157..e90aeab2edb0b 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs @@ -1,39 +1,40 @@ // Test `@` patterns combined with `box` patterns. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] #![feature(box_patterns)] #[derive(Copy, Clone)] struct C; -fn c() -> C { C } +fn c() -> C { + C +} struct NC; -fn nc() -> NC { NC } +fn nc() -> NC { + NC +} fn main() { let a @ box &b = Box::new(&C); - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + //~^ ERROR use of moved value let a @ box b = Box::new(C); - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + //~^ ERROR use of moved value fn f1(a @ box &b: Box<&C>) {} - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + //~^ ERROR use of moved value fn f2(a @ box b: Box) {} - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + //~^ ERROR use of moved value - match Box::new(C) { a @ box b => {} } - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + match Box::new(C) { + a @ box b => {} //~ ERROR use of moved value + } - let ref a @ box b = Box::new(NC); //~ ERROR cannot bind by-move and by-ref in the same pattern + let ref a @ box b = Box::new(NC); //~ ERROR cannot move out of `a` because it is borrowed let ref a @ box ref mut b = Box::new(nc()); //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable @@ -69,16 +70,4 @@ fn main() { 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 - _ => {} - } } diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr index e96c15b0fa7dd..50185c1a017d3 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr @@ -1,32 +1,14 @@ -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:16:9 - | -LL | let a @ box &b = Box::new(&C); - | ^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:20:9 - | -LL | let a @ box b = Box::new(C); - | ^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:32:25 - | -LL | match Box::new(C) { a @ box b => {} } - | ^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/borrowck-pat-at-and-box.rs:36:21 +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-at-and-box.rs:37:9 | LL | let ref a @ box b = Box::new(NC); - | ------------^ + | -----^^^^^^^- | | | - | | by-move pattern here - | by-ref pattern here + | | move out of `a` occurs here + | borrow of `a` occurs here error: cannot borrow `a` 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()); | -----^^^^^^^--------- @@ -35,7 +17,7 @@ LL | let ref a @ box ref mut b = Box::new(nc()); | immutable borrow occurs here error: cannot borrow `a` 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); | -----^^^^^^^--------- @@ -44,7 +26,7 @@ LL | let ref a @ box ref mut b = Box::new(NC); | immutable borrow occurs here error: cannot borrow `a` 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); | -----^^^^^^^--------- @@ -53,7 +35,7 @@ LL | let ref a @ box ref mut b = Box::new(NC); | immutable borrow occurs here error: cannot borrow `a` 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); | -----^^^^^^^--------- @@ -62,7 +44,7 @@ LL | let ref a @ box ref mut b = Box::new(NC); | immutable borrow occurs here error: cannot borrow `a` 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); | ---------^^^^^^^----- @@ -71,7 +53,7 @@ LL | let ref mut a @ box ref b = Box::new(NC); | mutable borrow occurs here error: cannot borrow `a` 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 => { | ---------^^^^^^^----- @@ -79,38 +61,8 @@ LL | ref mut a @ box ref b => { | | immutable borrow occurs here | mutable borrow occurs here -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/borrowck-pat-at-and-box.rs:74:38 - | -LL | box [Ok(a), ref xs @ .., Err(b)] => {} - | ----------- ^ by-move pattern here - | | - | by-ref pattern here - -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/borrowck-pat-at-and-box.rs:80:46 - | -LL | [Ok(box ref a), ref xs @ .., Err(box b), Err(box ref mut c)] => {} - | ----- ----------- ^ --------- by-ref pattern here - | | | | - | | | by-move pattern here - | | by-ref pattern here - | by-ref pattern here - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:24:11 - | -LL | fn f1(a @ box &b: Box<&C>) {} - | ^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:28:11 - | -LL | fn f2(a @ box b: Box) {} - | ^^^^^^^^^ 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 + --> $DIR/borrowck-pat-at-and-box.rs:58:11 | LL | fn f5(ref mut a @ box ref b: Box) { | ---------^^^^^^^----- @@ -119,7 +71,7 @@ LL | fn f5(ref mut a @ box ref b: Box) { | mutable borrow occurs here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:16:18 + --> $DIR/borrowck-pat-at-and-box.rs:21:18 | LL | let a @ box &b = Box::new(&C); | ---------^ ------------ move occurs because value has type `std::boxed::Box<&C>`, which does not implement the `Copy` trait @@ -128,7 +80,7 @@ LL | let a @ box &b = Box::new(&C); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:20:17 + --> $DIR/borrowck-pat-at-and-box.rs:24:17 | LL | let a @ box b = Box::new(C); | --------^ ----------- move occurs because value has type `std::boxed::Box`, which does not implement the `Copy` trait @@ -137,17 +89,18 @@ LL | let a @ box b = Box::new(C); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:32:33 + --> $DIR/borrowck-pat-at-and-box.rs:34:17 | -LL | match Box::new(C) { a @ box b => {} } - | ----------- --------^ - | | | | - | | | value used here after move - | | value moved here - | move occurs because value has type `std::boxed::Box`, which does not implement the `Copy` trait +LL | match Box::new(C) { + | ----------- move occurs because value has type `std::boxed::Box`, which does not implement the `Copy` trait +LL | a @ box b => {} + | --------^ + | | | + | | value used here after move + | value moved here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:45:21 + --> $DIR/borrowck-pat-at-and-box.rs:46:21 | LL | let ref a @ box ref mut b = Box::new(NC); | ------------^^^^^^^^^ @@ -159,7 +112,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:51:25 + --> $DIR/borrowck-pat-at-and-box.rs:52:25 | LL | let ref mut a @ box ref b = Box::new(NC); | ----------------^^^^^ @@ -171,7 +124,7 @@ LL | *a = Box::new(NC); | -- mutable borrow later used here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:65:25 + --> $DIR/borrowck-pat-at-and-box.rs:66:25 | LL | ref mut a @ box ref b => { | ----------------^^^^^ @@ -183,7 +136,7 @@ LL | *a = Box::new(NC); | -- mutable borrow later used here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:24:20 + --> $DIR/borrowck-pat-at-and-box.rs:27:20 | LL | fn f1(a @ box &b: Box<&C>) {} | ---------^ @@ -193,7 +146,7 @@ LL | fn f1(a @ box &b: Box<&C>) {} | move occurs because value has type `std::boxed::Box<&C>`, which does not implement the `Copy` trait error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:28:19 + --> $DIR/borrowck-pat-at-and-box.rs:30:19 | LL | fn f2(a @ box b: Box) {} | --------^ @@ -203,7 +156,7 @@ LL | fn f2(a @ box b: Box) {} | move occurs because value has type `std::boxed::Box`, which does not implement the `Copy` trait error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:57:27 + --> $DIR/borrowck-pat-at-and-box.rs:58:27 | LL | fn f5(ref mut a @ box ref b: Box) { | ----------------^^^^^ @@ -214,7 +167,7 @@ LL | fn f5(ref mut a @ box ref b: Box) { LL | *a = Box::new(NC); | -- mutable borrow later used here -error: aborting due to 24 previous errors +error: aborting due to 17 previous errors -Some errors have detailed explanations: E0007, E0009, E0382, E0502. -For more information about an error, try `rustc --explain E0007`. +Some errors have detailed explanations: E0382, E0502. +For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs new file mode 100644 index 0000000000000..1479791719313 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs @@ -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 +} diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr new file mode 100644 index 0000000000000..dc9201d0d061f --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr @@ -0,0 +1,12 @@ +error: borrow of moved value: `a` + --> $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 here + | move occurs because `a` has type `main::U` which does implement the `Copy` trait + +error: aborting due to previous error + diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs new file mode 100644 index 0000000000000..7d9618c8df78d --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs @@ -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 => {} + } +} diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr new file mode 100644 index 0000000000000..0c502cee7f6c9 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr @@ -0,0 +1,503 @@ +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:29:9 + | +LL | let a @ ref b = U; + | -^^^----- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $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 here + | move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait + +error: borrow of moved value: `b` + --> $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 here + | move occurs because `b` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `d` + --> $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 here + | move occurs because `d` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $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 here + | move occurs because `a` has type `[main::U; 2]` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:41:9 + | +LL | let a @ ref b = u(); + | -^^^----- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $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 here + | move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait + +error: borrow of moved value: `b` + --> $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 here + | move occurs because `b` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `d` + --> $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 here + | move occurs because `d` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $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 here + | move occurs because `a` has type `[main::U; 2]` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:56:9 + | +LL | a @ Some(ref b) => {} + | -^^^^^^^^-----^ + | | | + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `std::option::Option` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $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 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: `b` + --> $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 here + | move occurs because `b` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `d` + --> $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 here + | move occurs because `d` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $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 here + | move occurs because `a` has type `std::option::Option<[main::U; 2]>` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:77:9 + | +LL | a @ Some(ref b) => {} + | -^^^^^^^^-----^ + | | | + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `std::option::Option` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $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 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: `b` + --> $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 here + | move occurs because `b` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `d` + --> $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 here + | move occurs because `d` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $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 here + | move occurs because `a` has type `std::option::Option<[main::U; 2]>` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $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 here + | move occurs because `a` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $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 here + | move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait + +error: borrow of moved value: `b` + --> $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 here + | move occurs because `b` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `d` + --> $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 here + | move occurs because `d` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $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 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`, 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`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs index abe5ed81b71a2..4ece55b07b080 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs @@ -1,9 +1,74 @@ +// Test that `ref mut? @ pat_with_by_move_bindings` is prevented. + #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] fn main() { - match Some("hi".to_string()) { - ref op_string_ref @ Some(s) => {}, - //~^ ERROR cannot bind by-move and by-ref in the same pattern [E0009] - None => {}, + struct U; + + // Prevent promotion. + fn u() -> U { + U + } + + fn f1(ref a @ b: U) {} + //~^ ERROR cannot move out of `a` because it is borrowed + fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} + //~^ ERROR cannot move out of `a` because it is borrowed + //~| ERROR cannot move out of `b` because it is borrowed + //~| ERROR cannot move out of `d` because it is borrowed + fn f3(ref mut a @ [b, mut c]: [U; 2]) {} + //~^ ERROR cannot move out of `a` because it is borrowed + + let ref a @ b = U; + //~^ ERROR cannot move out of `a` because it is borrowed + let ref a @ (ref b @ mut c, ref d @ e) = (U, U); + //~^ ERROR cannot move out of `a` because it is borrowed + //~| ERROR cannot move out of `b` because it is borrowed + //~| ERROR cannot move out of `d` because it is borrowed + let ref mut a @ [b, mut c] = [U, U]; + //~^ ERROR cannot move out of `a` because it is borrowed + let ref a @ b = u(); + //~^ ERROR cannot move out of `a` because it is borrowed + let ref a @ (ref b @ mut c, ref d @ e) = (u(), u()); + //~^ ERROR cannot move out of `a` because it is borrowed + //~| ERROR cannot move out of `b` because it is borrowed + //~| ERROR cannot move out of `d` because it is borrowed + let ref mut a @ [b, mut c] = [u(), u()]; + //~^ ERROR cannot move out of `a` because it is borrowed + + match Some(U) { + ref a @ Some(b) => {} + //~^ ERROR cannot move out of `a` because it is borrowed + None => {} + } + match Some((U, U)) { + ref a @ Some((ref b @ mut c, ref d @ e)) => {} + //~^ ERROR cannot move out of `a` because it is borrowed + //~| ERROR cannot move out of `b` because it is borrowed + //~| ERROR cannot move out of `d` because it is borrowed + None => {} + } + match Some([U, U]) { + ref mut a @ Some([b, mut c]) => {} + //~^ ERROR cannot move out of `a` because it is borrowed + None => {} + } + match Some(u()) { + ref a @ Some(b) => {} + //~^ ERROR cannot move out of `a` because it is borrowed + None => {} + } + match Some((u(), u())) { + ref a @ Some((ref b @ mut c, ref d @ e)) => {} + //~^ ERROR cannot move out of `a` because it is borrowed + //~| ERROR cannot move out of `b` because it is borrowed + //~| ERROR cannot move out of `d` because it is borrowed + None => {} + } + match Some([u(), u()]) { + ref mut a @ Some([b, mut c]) => {} + //~^ ERROR cannot move out of `a` because it is borrowed + None => {} } } diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr index 1f70a6c437e92..607bbd5f991c0 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr @@ -1,12 +1,237 @@ -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/borrowck-pat-by-move-and-ref.rs:5:34 +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:23:9 | -LL | ref op_string_ref @ Some(s) => {}, - | -------------------------^- - | | | - | | by-move pattern here - | by-ref pattern here +LL | let ref a @ b = U; + | -----^^^- + | | | + | | move out of `a` occurs here + | borrow of `a` occurs here -error: aborting due to previous error +error: cannot move out of `a` 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); + | -----^^^^^^^^^^^^-----^^^^^^^^^^-^ + | | | | + | | | move out of `a` occurs here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `b` 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); + | -----^^^----- + | | | + | | move out of `b` occurs here + | borrow of `b` occurs here + +error: cannot move out of `d` 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); + | -----^^^- + | | | + | | move out of `d` occurs here + | borrow of `d` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:29:9 + | +LL | let ref mut a @ [b, mut c] = [U, U]; + | ---------^^^^-^^-----^ + | | | | + | | | move out of `a` occurs here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:31:9 + | +LL | let ref a @ b = u(); + | -----^^^- + | | | + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `a` 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()); + | -----^^^^^^^^^^^^-----^^^^^^^^^^-^ + | | | | + | | | move out of `a` occurs here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `b` 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()); + | -----^^^----- + | | | + | | move out of `b` occurs here + | borrow of `b` occurs here + +error: cannot move out of `d` 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()); + | -----^^^- + | | | + | | move out of `d` occurs here + | borrow of `d` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:37:9 + | +LL | let ref mut a @ [b, mut c] = [u(), u()]; + | ---------^^^^-^^-----^ + | | | | + | | | move out of `a` occurs here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:41:9 + | +LL | ref a @ Some(b) => {} + | -----^^^^^^^^-^ + | | | + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `a` 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)) => {} + | -----^^^^^^^^^^^^^^^^^-----^^^^^^^^^^-^^ + | | | | + | | | move out of `a` occurs here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `b` 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)) => {} + | -----^^^----- + | | | + | | move out of `b` occurs here + | borrow of `b` occurs here + +error: cannot move out of `d` 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)) => {} + | -----^^^- + | | | + | | move out of `d` occurs here + | borrow of `d` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:53:9 + | +LL | ref mut a @ Some([b, mut c]) => {} + | ---------^^^^^^^^^-^^-----^^ + | | | | + | | | move out of `a` occurs here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:58:9 + | +LL | ref a @ Some(b) => {} + | -----^^^^^^^^-^ + | | | + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `a` 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)) => {} + | -----^^^^^^^^^^^^^^^^^-----^^^^^^^^^^-^^ + | | | | + | | | move out of `a` occurs here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `b` 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)) => {} + | -----^^^----- + | | | + | | move out of `b` occurs here + | borrow of `b` occurs here + +error: cannot move out of `d` 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)) => {} + | -----^^^- + | | | + | | move out of `d` occurs here + | borrow of `d` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:70:9 + | +LL | ref mut a @ Some([b, mut c]) => {} + | ---------^^^^^^^^^-^^-----^^ + | | | | + | | | move out of `a` occurs here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:14:11 + | +LL | fn f1(ref a @ b: U) {} + | -----^^^- + | | | + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `a` 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)) {} + | -----^^^^^^^^^^^^-----^^^^^^^^^^-^ + | | | | + | | | move out of `a` occurs here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `b` 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)) {} + | -----^^^----- + | | | + | | move out of `b` occurs here + | borrow of `b` occurs here + +error: cannot move out of `d` 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)) {} + | -----^^^- + | | | + | | move out of `d` occurs here + | borrow of `d` occurs here + +error: cannot move out of `a` 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]) {} + | ---------^^^^-^^-----^ + | | | | + | | | move out of `a` occurs here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: aborting due to 25 previous errors -For more information about this error, try `rustc --explain E0009`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs index e8510dfa64999..a921ad056d81f 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs @@ -1,4 +1,5 @@ #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] enum Option { None, @@ -27,6 +28,9 @@ fn main() { //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + fn f4_also_moved(ref a @ ref mut b @ c: U) {} + //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~| ERROR cannot move out of `b` because it is borrowed let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub //~^ ERROR cannot borrow `a` as mutable more than once at a time diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr index 0d7b703f1816b..4652fffe36a42 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr @@ -1,5 +1,5 @@ error: cannot borrow `z` 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) => { | ---------^^^^^^^^^^^^^-----^ @@ -8,7 +8,7 @@ LL | ref mut z @ &mut Some(ref a) => { | mutable borrow occurs here error: cannot borrow `a` 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 | ---------^^^^-----------------^ @@ -18,7 +18,7 @@ LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | first mutable borrow occurs here error: cannot borrow `b` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:22 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:22 | LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | -----^^^--------- @@ -27,7 +27,7 @@ LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:39:9 | LL | let ref a @ ref mut b = U; | -----^^^--------- @@ -36,7 +36,7 @@ LL | let ref a @ ref mut b = U; | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:37:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:41:9 | LL | let ref mut a @ ref b = U; | ---------^^^----- @@ -45,7 +45,7 @@ LL | let ref mut a @ ref b = U; | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:39:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:43:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -55,7 +55,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:41:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:45:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ @@ -65,7 +65,7 @@ LL | let ref mut a @ (ref b, ref c) = (U, U); | mutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:44:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:48:9 | LL | let ref mut a @ ref b = u(); | ---------^^^----- @@ -74,7 +74,7 @@ LL | let ref mut a @ ref b = u(); | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:49:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:53:9 | LL | let ref a @ ref mut b = u(); | -----^^^--------- @@ -83,7 +83,7 @@ LL | let ref a @ ref mut b = u(); | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:55:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:59:9 | LL | let ref mut a @ ref b = U; | ---------^^^----- @@ -92,7 +92,7 @@ LL | let ref mut a @ ref b = U; | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:59:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:63:9 | LL | let ref a @ ref mut b = U; | -----^^^--------- @@ -101,7 +101,7 @@ LL | let ref a @ ref mut b = U; | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:65:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:69:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | ---------^^^^^^-----^ @@ -110,7 +110,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | mutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:65:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:69:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | ---------^^^^^^^-----^ @@ -119,7 +119,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----^^^^^^---------^ @@ -128,7 +128,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----^^^^^^^---------^ @@ -137,7 +137,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:9 + --> $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 } => {} | -----^^^^^^---------^ @@ -146,7 +146,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:33 + --> $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 } => {} | -----^^^^^^^---------^ @@ -155,7 +155,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:9 + --> $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 } => {} | ---------^^^^^^-----^ @@ -164,7 +164,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa | mutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:33 + --> $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 } => {} | ---------^^^^^^^-----^ @@ -173,7 +173,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:9 + --> $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 } => {} | -----^^^^^^---------^ @@ -182,7 +182,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:33 + --> $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 } => {} | -----^^^^^^^---------^ @@ -191,7 +191,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:9 + --> $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 } => {} | ---------^^^^^^-----^ @@ -200,7 +200,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false | mutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:33 + --> $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 } => {} | ---------^^^^^^^-----^ @@ -209,7 +209,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:115:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:119:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -219,7 +219,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:124:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -229,7 +229,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:131:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -239,7 +239,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:132:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:136:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ @@ -249,7 +249,7 @@ LL | let ref mut a @ (ref b, ref c) = (U, U); | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:24:11 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:25:11 | LL | fn f1(ref a @ ref mut b: U) {} | -----^^^--------- @@ -258,7 +258,7 @@ LL | fn f1(ref a @ ref mut b: U) {} | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:26:11 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:27:11 | LL | fn f2(ref mut a @ ref b: U) {} | ---------^^^----- @@ -267,7 +267,7 @@ LL | fn f2(ref mut a @ ref b: U) {} | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:11 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:29:11 | LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} | -----^^^^^^^^^^^----------------^^^^^^^^ @@ -275,8 +275,27 @@ LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} | | mutable borrow occurs here | immutable borrow occurs here +error: cannot borrow `a` 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 here + | | mutable borrow occurs here + | immutable borrow occurs here + +error: cannot move out of `b` 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) {} + | ---------^^^- + | | | + | | move out of `b` occurs here + | borrow of `b` occurs here + error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:10:31 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:31 | LL | ref mut z @ &mut Some(ref a) => { | ----------------------^^^^^- @@ -288,7 +307,7 @@ LL | **z = None; | ---------- mutable borrow later used here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:44:21 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:48:21 | LL | let ref mut a @ ref b = u(); | ------------^^^^^ @@ -300,7 +319,7 @@ LL | *a = u(); | -------- mutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:49:17 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:53:17 | LL | let ref a @ ref mut b = u(); | --------^^^^^^^^^ @@ -312,7 +331,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:20 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:20 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----------^^^^^^^^^- @@ -324,7 +343,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:45 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:45 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | ------------^^^^^^^^^- @@ -336,7 +355,7 @@ LL | drop(a); | - immutable borrow later used here error[E0594]: cannot assign to `*b`, as it is immutable for the pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:61 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:89:61 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | ^^^^^^ cannot assign @@ -344,7 +363,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } = note: variables bound in patterns are immutable until the end of the pattern guard error[E0594]: cannot assign to `*a`, as it is immutable for the pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:61 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96:61 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ^^^^^^^^^^^ cannot assign @@ -352,7 +371,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa = note: variables bound in patterns are immutable until the end of the pattern guard error[E0507]: cannot move out of `b` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:66 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | ^ move occurs because `b` has type `&mut main::U`, which does not implement the `Copy` trait @@ -360,7 +379,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0507]: cannot move out of `b` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:66 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | ^ move occurs because `b` has type `&mut main::U`, which does not implement the `Copy` trait @@ -368,7 +387,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0507]: cannot move out of `a` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:111:66 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ^ move occurs because `a` has type `&mut std::result::Result`, which does not implement the `Copy` trait @@ -376,7 +395,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0507]: cannot move out of `a` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:111:66 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ^ move occurs because `a` has type `&mut std::result::Result`, which does not implement the `Copy` trait @@ -384,7 +403,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:18 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:124:18 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | ---------^^^^^^^^^------------ @@ -396,7 +415,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:29 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:124:29 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | --------------------^^^^^^^^^- @@ -408,7 +427,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:18 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:131:18 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | ---------^^^^^^^^^------------ @@ -420,7 +439,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:29 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:131:29 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | --------------------^^^^^^^^^- @@ -431,7 +450,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); LL | drop(a); | - immutable borrow later used here -error: aborting due to 45 previous errors +error: aborting due to 47 previous errors Some errors have detailed explanations: E0502, E0507, E0594. For more information about an error, try `rustc --explain E0502`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs index f425b35630d17..77cd779d7167f 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs @@ -1,6 +1,7 @@ // Test that `ref mut x @ ref mut y` and varieties of that are not allowed. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] fn main() { struct U; @@ -20,6 +21,9 @@ fn main() { [..], ] : [[U; 4]; 5] ) {} + fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} + //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~| ERROR cannot move out of `b` because it is borrowed let ref mut a @ ref mut b = U; //~^ ERROR cannot borrow `a` as mutable more than once at a time @@ -60,18 +64,18 @@ fn main() { ) = (u(), [u(), u(), u()]); let a @ (ref mut b, ref mut c) = (U, U); - //~^ ERROR cannot bind by-move with sub-bindings + //~^ ERROR borrow of moved value //~| ERROR borrow of moved value let mut val = (U, [U, U]); let a @ (b, [c, d]) = &mut val; // Same as ^-- - //~^ ERROR cannot bind by-move with sub-bindings + //~^ ERROR borrow of moved value //~| ERROR borrow of moved value let a @ &mut ref mut b = &mut U; - //~^ ERROR cannot bind by-move with sub-bindings + //~^ ERROR borrow of moved value //~| ERROR borrow of moved value let a @ &mut (ref mut b, ref mut c) = &mut (U, U); - //~^ ERROR cannot bind by-move with sub-bindings + //~^ ERROR borrow of moved value //~| ERROR borrow of moved value match Ok(U) { diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr index d07ad140cc23a..a6d6678736475 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr @@ -1,5 +1,5 @@ error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:24:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:28:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -8,7 +8,7 @@ LL | let ref mut a @ ref mut b = U; | 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:32:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -17,7 +17,7 @@ LL | let ref mut a @ ref mut b = U; | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:31:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:35:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -26,7 +26,7 @@ LL | let ref mut a @ ref mut b = U; | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:34:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:38:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -35,7 +35,7 @@ LL | let ref mut a @ ref mut b = U; | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:38:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:42:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -44,7 +44,7 @@ LL | let ref mut a @ ref mut b = U; | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:42:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:46:9 | LL | let ref mut a @ ( | ^-------- @@ -66,7 +66,7 @@ LL | | ) = (U, [U, U, U]); | |_____^ error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:52:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:56:9 | LL | let ref mut a @ ( | ^-------- @@ -87,32 +87,52 @@ LL | | ] LL | | ) = (u(), [u(), u(), u()]); | |_________^ -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:62:9 +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-ref-mut-twice.rs:66:9 | 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 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 - --> $DIR/borrowck-pat-ref-mut-twice.rs:66:9 +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-ref-mut-twice.rs:70:9 | 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 here + | move occurs because `a` has type `&mut (main::U, [main::U; 2])` which does implement the `Copy` trait -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:70:9 +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-ref-mut-twice.rs:74:9 | LL | let a @ &mut ref mut b = &mut U; - | ^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it + | -^^^^^^^^--------- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `&mut main::U` which does implement the `Copy` trait -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:73:9 +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-ref-mut-twice.rs:77:9 | LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it + | -^^^^^^^^^---------^^---------^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `&mut (main::U, main::U)` which does implement the `Copy` trait error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:78:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:82:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -121,7 +141,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` 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) => { | ---------^^^^^^^---------^ @@ -130,7 +150,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` 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) => { | ---------^^^^^^---------^ @@ -139,7 +159,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` 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) => { | ---------^^^^^^^---------^ @@ -148,7 +168,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` 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) => { | ---------^^^^^^---------^ @@ -157,7 +177,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` 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) => { | ---------^^^^^^^---------^ @@ -166,7 +186,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` 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) => { | ---------^^^^^^---------^ @@ -175,7 +195,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` 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) => { | ---------^^^^^^^---------^ @@ -184,7 +204,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` 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) {} | ---------^^^--------- @@ -193,7 +213,7 @@ LL | fn f1(ref mut a @ ref mut b: U) {} | first mutable borrow occurs here error: cannot borrow `a` 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) {} | ---------^^^--------- @@ -202,7 +222,7 @@ LL | fn f2(ref mut a @ ref mut b: U) {} | first mutable borrow occurs here error: cannot borrow `a` 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 @ [ | ^-------- @@ -219,8 +239,27 @@ LL | | [..], LL | | ] : [[U; 4]; 5] | |_________^ +error: cannot borrow `a` 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 here + | | another mutable borrow occurs here + | first mutable borrow occurs here + +error: cannot move out of `b` 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) {} + | ---------^^^- + | | | + | | move out of `b` occurs here + | borrow of `b` occurs here + error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:24:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:28:21 | LL | let ref mut a @ ref mut b = U; | ------------^^^^^^^^^ @@ -232,7 +271,7 @@ LL | drop(a); | - first borrow later used here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:34:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:38:21 | LL | let ref mut a @ ref mut b = U; | ------------^^^^^^^^^ @@ -244,7 +283,7 @@ LL | *a = U; | ------ first borrow later used here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:62:25 + --> $DIR/borrowck-pat-ref-mut-twice.rs:66:25 | LL | let a @ (ref mut b, ref mut c) = (U, U); | ----------------^^^^^^^^^- ------ move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait @@ -253,7 +292,7 @@ LL | let a @ (ref mut b, ref mut c) = (U, U); | value moved here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:66:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:70:21 | LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- | ------------^-- -------- move occurs because value has type `&mut (main::U, [main::U; 2])`, which does not implement the `Copy` trait @@ -262,7 +301,7 @@ LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- | value moved here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:70:18 + --> $DIR/borrowck-pat-ref-mut-twice.rs:74:18 | LL | let a @ &mut ref mut b = &mut U; | ---------^^^^^^^^^ ------ move occurs because value has type `&mut main::U`, which does not implement the `Copy` trait @@ -271,7 +310,7 @@ LL | let a @ &mut ref mut b = &mut U; | value moved here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:73:30 + --> $DIR/borrowck-pat-ref-mut-twice.rs:77:30 | LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); | ---------------------^^^^^^^^^- ----------- move occurs because value has type `&mut (main::U, main::U)`, which does not implement the `Copy` trait @@ -280,7 +319,7 @@ LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); | value moved here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:91:24 + --> $DIR/borrowck-pat-ref-mut-twice.rs:95:24 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------------^^^^^^^^^- @@ -292,7 +331,7 @@ LL | *a = Err(U); | ----------- first borrow later used here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:91:53 + --> $DIR/borrowck-pat-ref-mut-twice.rs:95:53 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ----------------^^^^^^^^^- @@ -304,7 +343,7 @@ LL | *a = Err(U); | ----------- first borrow later used here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:103:24 + --> $DIR/borrowck-pat-ref-mut-twice.rs:107:24 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------------^^^^^^^^^- @@ -316,7 +355,7 @@ LL | drop(a); | - first borrow later used here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:103:53 + --> $DIR/borrowck-pat-ref-mut-twice.rs:107:53 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ----------------^^^^^^^^^- @@ -327,7 +366,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | drop(a); | - first borrow later used here -error: aborting due to 32 previous errors +error: aborting due to 34 previous errors -Some errors have detailed explanations: E0007, E0382, E0499. -For more information about an error, try `rustc --explain E0007`. +Some errors have detailed explanations: E0382, E0499. +For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs index db5aabc7a1453..821d4b42962bf 100644 --- a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs +++ b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs @@ -1,6 +1,7 @@ // Test that mixing `Copy` and non-`Copy` types in `@` patterns is forbidden. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] #[derive(Copy, Clone)] struct C; @@ -9,12 +10,9 @@ struct NC(A, B); fn main() { let a @ NC(b, c) = NC(C, C); - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + //~^ ERROR use of moved value let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C)); - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value - //~| ERROR cannot bind by-move with sub-bindings + //~^ ERROR use of moved value //~| ERROR use of moved value } diff --git a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr index cfc35d6c32a72..7e89008a60496 100644 --- a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr +++ b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr @@ -1,23 +1,5 @@ -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/copy-and-move-mixed.rs:11:9 - | -LL | let a @ NC(b, c) = NC(C, C); - | ^^^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/copy-and-move-mixed.rs:15:9 - | -LL | let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C)); - | ^^^^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/copy-and-move-mixed.rs:15:19 - | -LL | let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C)); - | ^^^^^^^^^^^^ binds an already bound by-move value by moving it - error[E0382]: use of moved value - --> $DIR/copy-and-move-mixed.rs:11:19 + --> $DIR/copy-and-move-mixed.rs:12:19 | LL | let a @ NC(b, c) = NC(C, C); | ----------^- -------- move occurs because value has type `NC`, 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`, which does not implement the `Copy` trait -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0007, E0382. -For more information about an error, try `rustc --explain E0007`. +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs index 1127d114145cd..94becb9e8b8e3 100644 --- a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs +++ b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs @@ -8,6 +8,7 @@ // this would create problems for the generalization aforementioned. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] fn main() { struct NotCopy; @@ -24,14 +25,26 @@ fn main() { let ref a @ b = &NotCopy; // OK let _: &&NotCopy = a; - let ref a @ b = NotCopy; //~ ERROR cannot bind by-move and by-ref in the same pattern - let ref mut a @ b = NotCopy; //~ ERROR cannot bind by-move and by-ref in the same pattern + let ref a @ b = NotCopy; //~ ERROR cannot move out of `a` because it is borrowed + let _a: &NotCopy = a; + let _b: NotCopy = b; + let ref mut a @ b = NotCopy; //~ ERROR cannot move out of `a` because it is borrowed + //~^ ERROR cannot move out of `_` because it is borrowed + let _a: &NotCopy = a; + let _b: NotCopy = b; match Ok(NotCopy) { - Ok(ref a @ b) | Err(ref a @ b) => {} - //~^ ERROR cannot bind by-move and by-ref in the same pattern + Ok(ref a @ b) | Err(b @ ref a) => { + //~^ ERROR cannot move out of `a` because it is borrowed + //~| ERROR borrow of moved value: `b` + let _a: &NotCopy = a; + let _b: NotCopy = b; + } } match NotCopy { - ref a @ b => {} - //~^ ERROR cannot bind by-move and by-ref in the same pattern + ref a @ b => { + //~^ ERROR cannot move out of `a` because it is borrowed + let _a: &NotCopy = a; + let _b: NotCopy = b; + } } } diff --git a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr index b6709a8a40e23..dfc6e16600e2a 100644 --- a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr +++ b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr @@ -1,41 +1,61 @@ -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/default-binding-modes-both-sides-independent.rs:27:17 +error: cannot move out of `a` because it is borrowed + --> $DIR/default-binding-modes-both-sides-independent.rs:28:9 | LL | let ref a @ b = NotCopy; - | --------^ + | -----^^^- | | | - | | by-move pattern here - | by-ref pattern here + | | move out of `a` occurs here + | borrow of `a` occurs here -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/default-binding-modes-both-sides-independent.rs:28:21 +error: cannot move out of `a` because it is borrowed + --> $DIR/default-binding-modes-both-sides-independent.rs:31:9 | LL | let ref mut a @ b = NotCopy; - | ------------^ + | ---------^^^- | | | - | | by-move pattern here - | by-ref pattern here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/default-binding-modes-both-sides-independent.rs:36:12 + | +LL | Ok(ref a @ b) | Err(b @ ref a) => { + | -----^^^- + | | | + | | move out of `a` occurs here + | borrow of `a` occurs here -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/default-binding-modes-both-sides-independent.rs:30:20 +error: borrow of moved value: `b` + --> $DIR/default-binding-modes-both-sides-independent.rs:36:29 | -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 +LL | Ok(ref a @ b) | Err(b @ ref a) => { + | -^^^----- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `b` has type `main::NotCopy` which does implement the `Copy` trait -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/default-binding-modes-both-sides-independent.rs:34:17 +error: cannot move out of `a` because it is borrowed + --> $DIR/default-binding-modes-both-sides-independent.rs:44:9 | -LL | ref a @ b => {} - | --------^ +LL | ref a @ b => { + | -----^^^- | | | - | | by-move pattern here - | by-ref pattern here + | | move out of `a` occurs here + | borrow of `a` occurs 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; + | ------------^ + | | | + | | move out of value occurs here + | borrow of value occurs here +LL | +LL | let _a: &NotCopy = a; + | - borrow later used here -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0009`. +For more information about this error, try `rustc --explain E0505`. diff --git a/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs new file mode 100644 index 0000000000000..d2d4e61e049b2 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs @@ -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; +} diff --git a/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.rs b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.rs new file mode 100644 index 0000000000000..3ee008fd84f09 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.rs @@ -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); +} diff --git a/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr new file mode 100644 index 0000000000000..d718ee29cf9b5 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr @@ -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`. diff --git a/src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.rs b/src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.rs new file mode 100644 index 0000000000000..fb92eb1ba32e0 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.rs @@ -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 +} diff --git a/src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.stderr b/src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.stderr new file mode 100644 index 0000000000000..8aef220c37519 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.stderr @@ -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`. diff --git a/src/test/ui/issues/issue-53840.rs b/src/test/ui/pattern/move-ref-patterns/issue-53840.rs similarity index 64% rename from src/test/ui/issues/issue-53840.rs rename to src/test/ui/pattern/move-ref-patterns/issue-53840.rs index e854d24ab9756..ab7d10d9f837d 100644 --- a/src/test/ui/issues/issue-53840.rs +++ b/src/test/ui/pattern/move-ref-patterns/issue-53840.rs @@ -1,3 +1,7 @@ +// check-pass + +#![feature(move_ref_pattern)] + enum E { Foo(String, String, String), } @@ -11,10 +15,8 @@ fn main() { let bar = Bar { a: "1".to_string(), b: "2".to_string() }; match E::Foo("".into(), "".into(), "".into()) { E::Foo(a, b, ref c) => {} -//~^ ERROR cannot bind by-move and by-ref in the same pattern } match bar { - Bar {a, ref b} => {} -//~^ ERROR cannot bind by-move and by-ref in the same pattern + Bar { a, ref b } => {} } } diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs new file mode 100644 index 0000000000000..e1844d36e4aa4 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs @@ -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::(_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); +} diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.rs b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.rs new file mode 100644 index 0000000000000..7f1c02c05cb0d --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.rs @@ -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::(_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); +} diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr new file mode 100644 index 0000000000000..ca82353c1c9ab --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr @@ -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::(_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::(_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`. diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.rs b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.rs new file mode 100644 index 0000000000000..5c51c47d9798a --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.rs @@ -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 +} diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.stderr b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.stderr new file mode 100644 index 0000000000000..fe7f71e6c46cd --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.stderr @@ -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`. diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-dynamic-semantics.rs b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-dynamic-semantics.rs new file mode 100644 index 0000000000000..c78695390b598 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-dynamic-semantics.rs @@ -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, + d: DropOrderListPtr, +} + +type DropOrderListPtr = Rc>>; + +impl Drop for X { + fn drop(&mut self) { + self.d.borrow_mut().push(*self.x); + } +} + +enum DoubleOption { + 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); +} diff --git a/src/test/ui/pattern/rest-pat-semantic-disallowed.rs b/src/test/ui/pattern/rest-pat-semantic-disallowed.rs index 31620216e82e1..84552f2e73315 100644 --- a/src/test/ui/pattern/rest-pat-semantic-disallowed.rs +++ b/src/test/ui/pattern/rest-pat-semantic-disallowed.rs @@ -2,7 +2,7 @@ // outside of slice (+ ident patterns witin those), tuple, // and tuple struct patterns and that duplicates are caught in these contexts. -#![feature(slice_patterns, box_patterns)] +#![feature(box_patterns)] fn main() {} diff --git a/src/test/ui/rfc-2005-default-binding-mode/for.rs b/src/test/ui/rfc-2005-default-binding-mode/for.rs index 3bf053eb874ce..aa42c7bb9c2f1 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/for.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/for.rs @@ -1,10 +1,11 @@ +#![feature(move_ref_pattern)] + struct Foo {} pub fn main() { - let mut tups = vec![(Foo{}, Foo{})]; + let mut tups = vec![(Foo {}, Foo {})]; // The below desugars to &(ref n, mut m). for (n, mut m) in &tups { - //~^ ERROR cannot bind by-move and by-ref in the same pattern - //~| ERROR cannot move out of a shared reference + //~^ ERROR cannot move out of a shared reference } } diff --git a/src/test/ui/rfc-2005-default-binding-mode/for.stderr b/src/test/ui/rfc-2005-default-binding-mode/for.stderr index ebc6ff5d8c3fe..ef62431388081 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/for.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/for.stderr @@ -1,13 +1,5 @@ -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/for.rs:6:13 - | -LL | for (n, mut m) in &tups { - | - ^^^^^ by-move pattern here - | | - | by-ref pattern here - error[E0507]: cannot move out of a shared reference - --> $DIR/for.rs:6:23 + --> $DIR/for.rs:8:23 | LL | for (n, mut m) in &tups { | ----- ^^^^^ @@ -15,7 +7,6 @@ LL | for (n, mut m) in &tups { | data moved here | move occurs because `m` has type `Foo`, which does not implement the `Copy` trait -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0009, E0507. -For more information about an error, try `rustc --explain E0009`. +For more information about this error, try `rustc --explain E0507`. From 0253f868cab2c5be84d354589b4b833aedbc9987 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 20 Jan 2020 11:03:30 +0100 Subject: [PATCH 3/6] move_ref_pattern: adjust error index --- src/librustc_error_codes/error_codes/E0009.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc_error_codes/error_codes/E0009.md b/src/librustc_error_codes/error_codes/E0009.md index abb7fe41ab7a2..aaabba0434993 100644 --- a/src/librustc_error_codes/error_codes/E0009.md +++ b/src/librustc_error_codes/error_codes/E0009.md @@ -1,3 +1,5 @@ +#### Note: this error code is no longer emitted by the compiler. + In a pattern, all values that don't implement the `Copy` trait have to be bound the same way. The goal here is to avoid binding simultaneously by-move and by-ref. @@ -6,7 +8,9 @@ This limitation may be removed in a future version of Rust. Erroneous code example: -```compile_fail,E0009 +``` +#![feature(move_ref_pattern)] + struct X { x: (), } let x = Some((X { x: () }, X { x: () })); From 8d4973f5871fd36b5946b9a06bd1157d4a87bbe0 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 2 Feb 2020 16:07:51 +0100 Subject: [PATCH 4/6] move_ref_pattern: don't ICE on unreachable 2xby-move conflicts --- .../hair/pattern/check_match.rs | 3 --- .../by-move-sub-pat-unreachable.rs | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/pattern/move-ref-patterns/by-move-sub-pat-unreachable.rs diff --git a/src/librustc_mir_build/hair/pattern/check_match.rs b/src/librustc_mir_build/hair/pattern/check_match.rs index a563864b61b31..0b01c9a06f9d4 100644 --- a/src/librustc_mir_build/hair/pattern/check_match.rs +++ b/src/librustc_mir_build/hair/pattern/check_match.rs @@ -648,9 +648,6 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat<'_ let mut conflicts_ref = Vec::new(); sub.each_binding(|_, hir_id, span, _| { match tables.extract_binding_mode(sess, hir_id, span) { - Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id, span) => { - sess.delay_span_bug(span, "by-move in subpat unchecked by borrowck"); - } Some(ty::BindByValue(_)) | None => {} Some(ty::BindByReference(_)) => conflicts_ref.push(span), } diff --git a/src/test/ui/pattern/move-ref-patterns/by-move-sub-pat-unreachable.rs b/src/test/ui/pattern/move-ref-patterns/by-move-sub-pat-unreachable.rs new file mode 100644 index 0000000000000..08fb5cd2e1688 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/by-move-sub-pat-unreachable.rs @@ -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); +} From bd318be05dab2e1149595aacbf3d808559fa42dc Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 2 Feb 2020 17:58:15 +0100 Subject: [PATCH 5/6] move_ref_pattern: change pov in diagnostics & add binding names --- .../hair/pattern/check_match.rs | 76 ++++--- ...her-can-live-while-the-other-survives-1.rs | 4 +- ...can-live-while-the-other-survives-1.stderr | 20 +- .../borrowck-pat-at-and-box.rs | 16 +- .../borrowck-pat-at-and-box.stderr | 48 ++-- ...t-by-move-and-ref-inverse-promotion.stderr | 4 +- ...orrowck-pat-by-move-and-ref-inverse.stderr | 100 ++++----- .../borrowck-pat-by-move-and-ref.rs | 50 ++--- .../borrowck-pat-by-move-and-ref.stderr | 170 +++++++------- .../borrowck-pat-ref-mut-and-ref.rs | 64 +++--- .../borrowck-pat-ref-mut-and-ref.stderr | 208 +++++++++--------- .../borrowck-pat-ref-mut-twice.rs | 40 ++-- .../borrowck-pat-ref-mut-twice.stderr | 152 ++++++------- ...lt-binding-modes-both-sides-independent.rs | 10 +- ...inding-modes-both-sides-independent.stderr | 28 +-- 15 files changed, 501 insertions(+), 489 deletions(-) diff --git a/src/librustc_mir_build/hair/pattern/check_match.rs b/src/librustc_mir_build/hair/pattern/check_match.rs index 0b01c9a06f9d4..b77bd4ecb8e1f 100644 --- a/src/librustc_mir_build/hair/pattern/check_match.rs +++ b/src/librustc_mir_build/hair/pattern/check_match.rs @@ -658,8 +658,8 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat<'_ name, tables.node_type(pat.hir_id), ); - sess.struct_span_err(pat.span, &format!("borrow of moved value: `{}`", name)) - .span_label(binding_span, "value moved here") + 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(); @@ -675,50 +675,62 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat<'_ let mut conflicts_move = Vec::new(); let mut conflicts_mut_mut = Vec::new(); let mut conflicts_mut_ref = Vec::new(); - sub.each_binding(|_, hir_id, span, _| match tables.extract_binding_mode(sess, hir_id, span) { - Some(ty::BindByReference(mut_inner)) => match (mut_outer, mut_inner) { - (Mutability::Not, Mutability::Not) => {} // Both sides are `ref`. - (Mutability::Mut, Mutability::Mut) => conflicts_mut_mut.push(span), // 2x `ref mut`. - _ => conflicts_mut_ref.push(span), // `ref` + `ref mut` in either direction. - }, - Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id, span) => { - conflicts_move.push(span) // `ref mut?` + by-move conflict. + sub.each_binding(|_, hir_id, span, name| { + match tables.extract_binding_mode(sess, hir_id, span) { + Some(ty::BindByReference(mut_inner)) => match (mut_outer, mut_inner) { + (Mutability::Not, Mutability::Not) => {} // Both sides are `ref`. + (Mutability::Mut, Mutability::Mut) => conflicts_mut_mut.push((span, name)), // 2x `ref mut`. + _ => conflicts_mut_ref.push((span, name)), // `ref` + `ref mut` in either direction. + }, + Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id, span) => { + conflicts_move.push((span, name)) // `ref mut?` + by-move conflict. + } + Some(ty::BindByValue(_)) | None => {} // `ref mut?` + by-copy is fine. } - Some(ty::BindByValue(_)) | None => {} // `ref mut?` + by-copy is fine. }); // Report errors if any. if !conflicts_mut_mut.is_empty() { // Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`. - let msg = &format!("cannot borrow `{}` as mutable more than once at a time", name); - sess.struct_span_err(pat.span, msg) - .span_label(binding_span, "first mutable borrow occurs here") - .span_labels(conflicts_mut_mut, "another mutable borrow occurs here") - .span_labels(conflicts_mut_ref, "also borrowed as immutable here") - .span_labels(conflicts_move, "also moved here") - .emit(); + 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 `{}` as {} because it is also borrowed as {}", - name, also, primary, - ); - sess.struct_span_err(pat.span, msg) - .span_label(binding_span, format!("{} borrow occurs here", primary)) - .span_labels(conflicts_mut_ref, format!("{} borrow occurs here", also)) - .span_labels(conflicts_move, "also moved here") - .emit(); + 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 msg = &format!("cannot move out of `{}` because it is borrowed", name); - sess.struct_span_err(pat.span, msg) - .span_label(binding_span, format!("borrow of `{}` occurs here", name)) - .span_labels(conflicts_move, format!("move out of `{}` occurs here", name)) - .emit(); + 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(); } } diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs index 1cad822382677..c00296c34c4e5 100644 --- a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs @@ -12,7 +12,7 @@ struct X { fn main() { let x = Some(X { x: () }); match x { - Some(ref _y @ _z) => {} //~ ERROR cannot move out of `_y` because it is borrowed + Some(ref _y @ _z) => {} //~ ERROR cannot move out of value because it is borrowed None => panic!(), } @@ -26,7 +26,7 @@ fn main() { let mut x = Some(X { x: () }); match x { - Some(ref mut _y @ _z) => {} //~ ERROR cannot move out of `_y` because it is borrowed + Some(ref mut _y @ _z) => {} //~ ERROR cannot move out of value because it is borrowed None => panic!(), } diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr index 6ad0248fc6b2f..026747c212a2c 100644 --- a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr @@ -1,39 +1,39 @@ -error: cannot move out of `_y` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:15:14 | LL | Some(ref _y @ _z) => {} | ------^^^-- | | | - | | move out of `_y` occurs here - | borrow of `_y` occurs here + | | value moved into `_z` here + | value borrowed, by `_y`, here -error: borrow of moved value: `_z` +error: borrow of moved value --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:21:14 | LL | Some(_z @ ref _y) => {} | --^^^------ | | | | | value borrowed here after move - | value moved here + | value moved into `_z` here | move occurs because `_z` has type `X` which does implement the `Copy` trait -error: cannot move out of `_y` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:29:14 | LL | Some(ref mut _y @ _z) => {} | ----------^^^-- | | | - | | move out of `_y` occurs here - | borrow of `_y` occurs here + | | value moved into `_z` here + | value borrowed, by `_y`, here -error: borrow of moved value: `_z` +error: borrow of moved value --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:35:14 | LL | Some(_z @ ref mut _y) => {} | --^^^---------- | | | | | value borrowed here after move - | value moved here + | value moved into `_z` here | move occurs because `_z` has type `X` which does implement the `Copy` trait error[E0382]: borrow of moved value diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs index e90aeab2edb0b..32c638bcbcca3 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs @@ -34,29 +34,29 @@ fn main() { a @ box b => {} //~ ERROR use of moved value } - let ref a @ box b = Box::new(NC); //~ ERROR cannot move out of `a` because it is borrowed + let ref a @ box b = Box::new(NC); //~ ERROR cannot move out of value because it is borrowed let ref a @ box ref mut b = Box::new(nc()); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable let ref a @ box ref mut b = Box::new(NC); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable let ref a @ box ref mut b = Box::new(NC); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable *b = NC; let ref a @ box ref mut b = Box::new(NC); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable *b = NC; drop(a); let ref mut a @ box ref b = Box::new(NC); - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable *a = Box::new(NC); drop(b); fn f5(ref mut a @ box ref b: Box) { - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable *a = Box::new(NC); drop(b); @@ -64,7 +64,7 @@ fn main() { match Box::new(nc()) { ref mut a @ box ref b => { - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable *a = Box::new(NC); drop(b); diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr index 50185c1a017d3..5534d0a75e63d 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr @@ -1,74 +1,74 @@ -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-at-and-box.rs:37:9 | LL | let ref a @ box b = Box::new(NC); | -----^^^^^^^- | | | - | | move out of `a` occurs here - | borrow of `a` occurs here + | | value moved into `b` 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:39:9 | LL | let ref a @ box ref mut b = Box::new(nc()); | -----^^^^^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-at-and-box.rs:41:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-at-and-box.rs:43:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-at-and-box.rs:46:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-at-and-box.rs:52:9 | LL | let ref mut a @ box ref b = Box::new(NC); | ---------^^^^^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-at-and-box.rs:66:9 | LL | ref mut a @ box ref b => { | ---------^^^^^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: 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:58:11 | LL | fn f5(ref mut a @ box ref b: Box) { | ---------^^^^^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here error[E0382]: use of moved value --> $DIR/borrowck-pat-at-and-box.rs:21:18 diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr index dc9201d0d061f..91fdfd4f2abcc 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr @@ -1,11 +1,11 @@ -error: borrow of moved value: `a` +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 here + | 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 diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr index 0c502cee7f6c9..ec86692dc6962 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr @@ -1,14 +1,14 @@ -error: borrow of moved value: `a` +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 here + | value moved into `a` here | move occurs because `a` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `a` +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); @@ -16,30 +16,30 @@ 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 here + | 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: `b` +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 here + | value moved into `b` here | move occurs because `b` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `d` +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 here + | value moved into `d` here | move occurs because `d` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `a` +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]; @@ -47,20 +47,20 @@ LL | let a @ [ref mut b, ref c] = [U, U]; | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | 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: `a` +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 here + | value moved into `a` here | move occurs because `a` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `a` +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()); @@ -68,30 +68,30 @@ 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 here + | 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: `b` +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 here + | value moved into `b` here | move occurs because `b` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `d` +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 here + | value moved into `d` here | move occurs because `d` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `a` +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()]; @@ -99,20 +99,20 @@ LL | let a @ [ref mut b, ref c] = [u(), u()]; | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | 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: `a` +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 here + | value moved into `a` here | move occurs because `a` has type `std::option::Option` which does implement the `Copy` trait -error: borrow of moved value: `a` +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)) => {} @@ -120,30 +120,30 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | 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: `b` +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 here + | value moved into `b` here | move occurs because `b` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `d` +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 here + | value moved into `d` here | move occurs because `d` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `a` +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]) => {} @@ -151,20 +151,20 @@ LL | mut a @ Some([ref b, ref mut c]) => {} | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | 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: `a` +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 here + | value moved into `a` here | move occurs because `a` has type `std::option::Option` which does implement the `Copy` trait -error: borrow of moved value: `a` +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)) => {} @@ -172,30 +172,30 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | 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: `b` +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 here + | value moved into `b` here | move occurs because `b` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `d` +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 here + | value moved into `d` here | move occurs because `d` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `a` +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]) => {} @@ -203,20 +203,20 @@ LL | mut a @ Some([ref b, ref mut c]) => {} | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | 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: `a` +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 here + | value moved into `a` here | move occurs because `a` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `a` +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)) {} @@ -224,30 +224,30 @@ 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 here + | 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: `b` +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 here + | value moved into `b` here | move occurs because `b` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `d` +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 here + | value moved into `d` here | move occurs because `d` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `a` +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]) {} @@ -255,7 +255,7 @@ LL | fn f3(a @ [ref mut b, ref c]: [U; 2]) {} | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | 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 diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs index 4ece55b07b080..b7c8c8766c00a 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs @@ -12,63 +12,63 @@ fn main() { } fn f1(ref a @ b: U) {} - //~^ ERROR cannot move out of `a` because it is borrowed + //~^ 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 `a` because it is borrowed - //~| ERROR cannot move out of `b` because it is borrowed - //~| ERROR cannot move out of `d` because it is borrowed + //~^ 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 `a` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed let ref a @ b = U; - //~^ ERROR cannot move out of `a` because it is borrowed + //~^ 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 `a` because it is borrowed - //~| ERROR cannot move out of `b` because it is borrowed - //~| ERROR cannot move out of `d` because it is borrowed + //~^ 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 `a` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed let ref a @ b = u(); - //~^ ERROR cannot move out of `a` because it is borrowed + //~^ 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 `a` because it is borrowed - //~| ERROR cannot move out of `b` because it is borrowed - //~| ERROR cannot move out of `d` because it is borrowed + //~^ 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 `a` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed match Some(U) { ref a @ Some(b) => {} - //~^ ERROR cannot move out of `a` because it is borrowed + //~^ 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 `a` because it is borrowed - //~| ERROR cannot move out of `b` because it is borrowed - //~| ERROR cannot move out of `d` because it is borrowed + //~^ 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 `a` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed None => {} } match Some(u()) { ref a @ Some(b) => {} - //~^ ERROR cannot move out of `a` because it is borrowed + //~^ 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 `a` because it is borrowed - //~| ERROR cannot move out of `b` because it is borrowed - //~| ERROR cannot move out of `d` because it is borrowed + //~^ 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 `a` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed None => {} } } diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr index 607bbd5f991c0..e5419efa00b36 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr @@ -1,237 +1,237 @@ -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:23:9 | LL | let ref a @ b = U; | -----^^^- | | | - | | move out of `a` occurs here - | borrow of `a` occurs here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +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); | -----^^^^^^^^^^^^-----^^^^^^^^^^-^ | | | | - | | | move out of `a` occurs here - | | move out of `a` occurs here - | borrow of `a` occurs here + | | | value moved into `e` here + | | value moved into `c` here + | value borrowed, by `a`, here -error: cannot move out of `b` because it is borrowed +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); | -----^^^----- | | | - | | move out of `b` occurs here - | borrow of `b` occurs here + | | value moved into `c` here + | value borrowed, by `b`, here -error: cannot move out of `d` because it is borrowed +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); | -----^^^- | | | - | | move out of `d` occurs here - | borrow of `d` occurs here + | | value moved into `e` here + | value borrowed, by `d`, here -error: cannot move out of `a` because it is borrowed +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]; | ---------^^^^-^^-----^ | | | | - | | | move out of `a` occurs here - | | move out of `a` occurs here - | borrow of `a` occurs here + | | | value moved into `c` here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +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(); | -----^^^- | | | - | | move out of `a` occurs here - | borrow of `a` occurs here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +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()); | -----^^^^^^^^^^^^-----^^^^^^^^^^-^ | | | | - | | | move out of `a` occurs here - | | move out of `a` occurs here - | borrow of `a` occurs here + | | | value moved into `e` here + | | value moved into `c` here + | value borrowed, by `a`, here -error: cannot move out of `b` because it is borrowed +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()); | -----^^^----- | | | - | | move out of `b` occurs here - | borrow of `b` occurs here + | | value moved into `c` here + | value borrowed, by `b`, here -error: cannot move out of `d` because it is borrowed +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()); | -----^^^- | | | - | | move out of `d` occurs here - | borrow of `d` occurs here + | | value moved into `e` here + | value borrowed, by `d`, here -error: cannot move out of `a` because it is borrowed +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()]; | ---------^^^^-^^-----^ | | | | - | | | move out of `a` occurs here - | | move out of `a` occurs here - | borrow of `a` occurs here + | | | value moved into `c` here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +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) => {} | -----^^^^^^^^-^ | | | - | | move out of `a` occurs here - | borrow of `a` occurs here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +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)) => {} | -----^^^^^^^^^^^^^^^^^-----^^^^^^^^^^-^^ | | | | - | | | move out of `a` occurs here - | | move out of `a` occurs here - | borrow of `a` occurs here + | | | value moved into `e` here + | | value moved into `c` here + | value borrowed, by `a`, here -error: cannot move out of `b` because it is borrowed +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)) => {} | -----^^^----- | | | - | | move out of `b` occurs here - | borrow of `b` occurs here + | | value moved into `c` here + | value borrowed, by `b`, here -error: cannot move out of `d` because it is borrowed +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)) => {} | -----^^^- | | | - | | move out of `d` occurs here - | borrow of `d` occurs here + | | value moved into `e` here + | value borrowed, by `d`, here -error: cannot move out of `a` because it is borrowed +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]) => {} | ---------^^^^^^^^^-^^-----^^ | | | | - | | | move out of `a` occurs here - | | move out of `a` occurs here - | borrow of `a` occurs here + | | | value moved into `c` here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +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) => {} | -----^^^^^^^^-^ | | | - | | move out of `a` occurs here - | borrow of `a` occurs here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +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)) => {} | -----^^^^^^^^^^^^^^^^^-----^^^^^^^^^^-^^ | | | | - | | | move out of `a` occurs here - | | move out of `a` occurs here - | borrow of `a` occurs here + | | | value moved into `e` here + | | value moved into `c` here + | value borrowed, by `a`, here -error: cannot move out of `b` because it is borrowed +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)) => {} | -----^^^----- | | | - | | move out of `b` occurs here - | borrow of `b` occurs here + | | value moved into `c` here + | value borrowed, by `b`, here -error: cannot move out of `d` because it is borrowed +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)) => {} | -----^^^- | | | - | | move out of `d` occurs here - | borrow of `d` occurs here + | | value moved into `e` here + | value borrowed, by `d`, here -error: cannot move out of `a` because it is borrowed +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]) => {} | ---------^^^^^^^^^-^^-----^^ | | | | - | | | move out of `a` occurs here - | | move out of `a` occurs here - | borrow of `a` occurs here + | | | value moved into `c` here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +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) {} | -----^^^- | | | - | | move out of `a` occurs here - | borrow of `a` occurs here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +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)) {} | -----^^^^^^^^^^^^-----^^^^^^^^^^-^ | | | | - | | | move out of `a` occurs here - | | move out of `a` occurs here - | borrow of `a` occurs here + | | | value moved into `e` here + | | value moved into `c` here + | value borrowed, by `a`, here -error: cannot move out of `b` because it is borrowed +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)) {} | -----^^^----- | | | - | | move out of `b` occurs here - | borrow of `b` occurs here + | | value moved into `c` here + | value borrowed, by `b`, here -error: cannot move out of `d` because it is borrowed +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)) {} | -----^^^- | | | - | | move out of `d` occurs here - | borrow of `d` occurs here + | | value moved into `e` here + | value borrowed, by `d`, here -error: cannot move out of `a` because it is borrowed +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]) {} | ---------^^^^-^^-----^ | | | | - | | | move out of `a` occurs here - | | move out of `a` occurs here - | borrow of `a` occurs here + | | | value moved into `c` here + | | value moved into `b` here + | value borrowed, by `a`, here error: aborting due to 25 previous errors diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs index a921ad056d81f..58d4a9b018cee 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs @@ -9,7 +9,7 @@ enum Option { fn main() { match &mut Some(1) { ref mut z @ &mut Some(ref a) => { - //~^ ERROR cannot borrow `z` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable **z = None; println!("{}", *a); @@ -23,52 +23,52 @@ fn main() { fn u() -> U { U } fn f1(ref a @ ref mut b: U) {} - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable fn f2(ref mut a @ ref b: U) {} - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable fn f4_also_moved(ref a @ ref mut b @ c: U) {} - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable - //~| ERROR cannot move out of `b` because it is borrowed + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable + //~| ERROR cannot move out of value because it is borrowed let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub - //~^ ERROR cannot borrow `a` as mutable more than once at a time - //~| ERROR cannot borrow `b` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable more than once at a time + //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable let ref a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable let ref mut a @ ref b = U; - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable let ref a @ (ref mut b, ref mut c) = (U, U); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable let ref mut a @ (ref b, ref c) = (U, U); - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable let ref mut a @ ref b = u(); - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable *a = u(); drop(b); let ref a @ ref mut b = u(); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable *b = u(); drop(a); let ref mut a @ ref b = U; - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable *a = U; drop(b); let ref a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable *b = U; drop(a); match Ok(U) { ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable - //~| ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable + //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable *a = Err(U); drop(b); } @@ -76,8 +76,8 @@ fn main() { match Ok(U) { ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable - //~| ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable + //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable *b = U; @@ -87,52 +87,52 @@ fn main() { match Ok(U) { ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable - //~| ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable + //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot assign to `*b`, as it is immutable for the pattern guard _ => {} } match Ok(U) { ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable - //~| ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable + //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot assign to `*a`, as it is immutable for the pattern guard _ => {} } match Ok(U) { ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable - //~| ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable + //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot move out of `b` in pattern guard //~| ERROR cannot move out of `b` in pattern guard _ => {} } match Ok(U) { ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable - //~| ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable + //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot move out of `a` in pattern guard //~| ERROR cannot move out of `a` in pattern guard _ => {} } let ref a @ (ref mut b, ref mut c) = (U, U); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable *b = U; *c = U; let ref a @ (ref mut b, ref mut c) = (U, U); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable *b = U; drop(a); let ref a @ (ref mut b, ref mut c) = (U, U); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable *b = U; //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable *c = U; //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable drop(a); let ref mut a @ (ref b, ref c) = (U, U); - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable } diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr index 4652fffe36a42..8c6ca888e0762 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr @@ -1,298 +1,298 @@ -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:11:9 | LL | ref mut z @ &mut Some(ref a) => { | ---------^^^^^^^^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `a`, occurs here + | mutable borrow, by `z`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:9 | LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | ---------^^^^-----------------^ | | | | - | | | another mutable borrow occurs here - | | also borrowed as immutable here - | first mutable borrow occurs here + | | | another mutable borrow, by `c`, occurs here + | | also borrowed as immutable, by `b`, here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `b` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:22 | LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | -----^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `c`, occurs here + | immutable borrow, by `b`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:39:9 | LL | let ref a @ ref mut b = U; | -----^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:41:9 | LL | let ref mut a @ ref b = U; | ---------^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:43:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ | | | | - | | | mutable borrow occurs here - | | mutable borrow occurs here - | immutable borrow occurs here + | | | mutable borrow, by `c`, occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:45:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ | | | | - | | | immutable borrow occurs here - | | immutable borrow occurs here - | mutable borrow occurs here + | | | immutable borrow, by `c`, occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:48:9 | LL | let ref mut a @ ref b = u(); | ---------^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:53:9 | LL | let ref a @ ref mut b = u(); | -----^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:59:9 | LL | let ref mut a @ ref b = U; | ---------^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:63:9 | LL | let ref a @ ref mut b = U; | -----^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:69:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | ---------^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:69:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | ---------^^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----^^^^^^---------^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----^^^^^^^---------^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:89:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | -----^^^^^^---------^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:89:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | -----^^^^^^^---------^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ---------^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ---------^^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | -----^^^^^^---------^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | -----^^^^^^^---------^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:111:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ---------^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:111:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ---------^^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:119:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ | | | | - | | | mutable borrow occurs here - | | mutable borrow occurs here - | immutable borrow occurs here + | | | mutable borrow, by `c`, occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:124:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ | | | | - | | | mutable borrow occurs here - | | mutable borrow occurs here - | immutable borrow occurs here + | | | mutable borrow, by `c`, occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:131:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ | | | | - | | | mutable borrow occurs here - | | mutable borrow occurs here - | immutable borrow occurs here + | | | mutable borrow, by `c`, occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:136:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ | | | | - | | | immutable borrow occurs here - | | immutable borrow occurs here - | mutable borrow occurs here + | | | immutable borrow, by `c`, occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:25:11 | LL | fn f1(ref a @ ref mut b: U) {} | -----^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:27:11 | LL | fn f2(ref mut a @ ref b: U) {} | ---------^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:29:11 | LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} | -----^^^^^^^^^^^----------------^^^^^^^^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `mid`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `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:31:22 | LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} | -----^^^------------- | | | | - | | | also moved here - | | mutable borrow occurs here - | immutable borrow occurs here + | | | also moved into `c` here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot move out of `b` because it is borrowed +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) {} | ---------^^^- | | | - | | move out of `b` occurs here - | borrow of `b` occurs here + | | value moved into `c` here + | value borrowed, by `b`, here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:31 diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs index 77cd779d7167f..f5c39a7ac5276 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs @@ -9,12 +9,12 @@ fn main() { fn u() -> U { U } fn f1(ref mut a @ ref mut b: U) {} - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time fn f2(ref mut a @ ref mut b: U) {} - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time fn f3( ref mut a @ [ - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time [ref b @ .., _], [_, ref mut mid @ ..], .., @@ -22,29 +22,29 @@ fn main() { ] : [[U; 4]; 5] ) {} fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} - //~^ ERROR cannot borrow `a` as mutable more than once at a time - //~| ERROR cannot move out of `b` because it is borrowed + //~^ ERROR cannot borrow value as mutable more than once at a time + //~| ERROR cannot move out of value because it is borrowed let ref mut a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time drop(a); let ref mut a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time drop(b); let ref mut a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time let ref mut a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time *a = U; let ref mut a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time *b = U; let ref mut a @ ( - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time ref mut b, [ ref mut c, @@ -54,7 +54,7 @@ fn main() { ) = (U, [U, U, U]); let ref mut a @ ( - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time ref mut b, [ ref mut c, @@ -80,21 +80,21 @@ fn main() { match Ok(U) { ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { - //~^ ERROR cannot borrow `a` as mutable more than once at a time - //~| ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time + //~| ERROR cannot borrow value as mutable more than once at a time } } match Ok(U) { ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { - //~^ ERROR cannot borrow `a` as mutable more than once at a time - //~| ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time + //~| ERROR cannot borrow value as mutable more than once at a time *b = U; } } match Ok(U) { ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { - //~^ ERROR cannot borrow `a` as mutable more than once at a time - //~| ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time + //~| ERROR cannot borrow value as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time *a = Err(U); @@ -105,8 +105,8 @@ fn main() { } match Ok(U) { ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { - //~^ ERROR cannot borrow `a` as mutable more than once at a time - //~| ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time + //~| ERROR cannot borrow value as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time drop(a); diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr index a6d6678736475..4e96c6e1669c7 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr @@ -1,93 +1,93 @@ -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:28:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:32:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:35:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:38:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:42:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:46:9 | LL | let ref mut a @ ( | ^-------- | | - | _________first mutable borrow occurs here + | _________first mutable borrow, by `a`, occurs here | | LL | | LL | | ref mut b, - | | --------- another mutable borrow occurs here + | | --------- another mutable borrow, by `b`, occurs here LL | | [ LL | | ref mut c, - | | --------- another mutable borrow occurs here + | | --------- another mutable borrow, by `c`, occurs here LL | | ref mut d, - | | --------- another mutable borrow occurs here + | | --------- another mutable borrow, by `d`, occurs here LL | | ref e, - | | ----- also borrowed as immutable here + | | ----- also borrowed as immutable, by `e`, here LL | | ] LL | | ) = (U, [U, U, U]); | |_____^ -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:56:9 | LL | let ref mut a @ ( | ^-------- | | - | _________first mutable borrow occurs here + | _________first mutable borrow, by `a`, occurs here | | LL | | LL | | ref mut b, - | | --------- another mutable borrow occurs here + | | --------- another mutable borrow, by `b`, occurs here LL | | [ LL | | ref mut c, - | | --------- another mutable borrow occurs here + | | --------- another mutable borrow, by `c`, occurs here LL | | ref mut d, - | | --------- another mutable borrow occurs here + | | --------- another mutable borrow, by `d`, occurs here LL | | ref e, - | | ----- also borrowed as immutable here + | | ----- also borrowed as immutable, by `e`, here LL | | ] LL | | ) = (u(), [u(), u(), u()]); | |_________^ -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-ref-mut-twice.rs:66:9 | LL | let a @ (ref mut b, ref mut c) = (U, U); @@ -95,10 +95,10 @@ LL | let a @ (ref mut b, ref mut c) = (U, U); | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | 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: `a` +error: borrow of moved value --> $DIR/borrowck-pat-ref-mut-twice.rs:70:9 | LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- @@ -107,20 +107,20 @@ LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- | | | | value borrowed here after move | | | value borrowed here after move | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `&mut (main::U, [main::U; 2])` which does implement the `Copy` trait -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-ref-mut-twice.rs:74:9 | LL | let a @ &mut ref mut b = &mut U; | -^^^^^^^^--------- | | | | | value borrowed here after move - | value moved here + | 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: `a` +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); @@ -128,135 +128,135 @@ LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | 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:82:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:82:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:88:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:88:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:95:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:95:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:107:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:107:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:11:11 | LL | fn f1(ref mut a @ ref mut b: U) {} | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:13:11 | LL | fn f2(ref mut a @ ref mut b: U) {} | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:16:9 | LL | ref mut a @ [ | ^-------- | | - | _________first mutable borrow occurs here + | _________first mutable borrow, by `a`, occurs here | | LL | | LL | | [ref b @ .., _], - | | ---------- also borrowed as immutable here + | | ---------- also borrowed as immutable, by `b`, here LL | | [_, ref mut mid @ ..], - | | ---------------- another mutable borrow occurs here + | | ---------------- another mutable borrow, by `mid`, occurs here LL | | .., LL | | [..], LL | | ] : [[U; 4]; 5] | |_________^ -error: cannot borrow `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:22 | LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} | ---------^^^------------- | | | | - | | | also moved here - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | | also moved into `c` here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot move out of `b` because it is borrowed +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) {} | ---------^^^- | | | - | | move out of `b` occurs here - | borrow of `b` occurs here + | | value moved into `c` here + | value borrowed, by `b`, here error[E0499]: cannot borrow `_` as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:28:21 diff --git a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs index 94becb9e8b8e3..b40c3e3358aa3 100644 --- a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs +++ b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs @@ -25,24 +25,24 @@ fn main() { let ref a @ b = &NotCopy; // OK let _: &&NotCopy = a; - let ref a @ b = NotCopy; //~ ERROR cannot move out of `a` because it is borrowed + let ref a @ b = NotCopy; //~ ERROR cannot move out of value because it is borrowed let _a: &NotCopy = a; let _b: NotCopy = b; - let ref mut a @ b = NotCopy; //~ ERROR cannot move out of `a` because it is borrowed + let ref mut a @ b = NotCopy; //~ ERROR cannot move out of value because it is borrowed //~^ ERROR cannot move out of `_` because it is borrowed let _a: &NotCopy = a; let _b: NotCopy = b; match Ok(NotCopy) { Ok(ref a @ b) | Err(b @ ref a) => { - //~^ ERROR cannot move out of `a` because it is borrowed - //~| ERROR borrow of moved value: `b` + //~^ ERROR cannot move out of value because it is borrowed + //~| ERROR borrow of moved value let _a: &NotCopy = a; let _b: NotCopy = b; } } match NotCopy { ref a @ b => { - //~^ ERROR cannot move out of `a` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed let _a: &NotCopy = a; let _b: NotCopy = b; } diff --git a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr index dfc6e16600e2a..697a8b96e6318 100644 --- a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr +++ b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr @@ -1,48 +1,48 @@ -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/default-binding-modes-both-sides-independent.rs:28:9 | LL | let ref a @ b = NotCopy; | -----^^^- | | | - | | move out of `a` occurs here - | borrow of `a` occurs here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/default-binding-modes-both-sides-independent.rs:31:9 | LL | let ref mut a @ b = NotCopy; | ---------^^^- | | | - | | move out of `a` occurs here - | borrow of `a` occurs here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +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) => { | -----^^^- | | | - | | move out of `a` occurs here - | borrow of `a` occurs here + | | value moved into `b` here + | value borrowed, by `a`, here -error: borrow of moved value: `b` +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 here + | value moved into `b` here | move occurs because `b` has type `main::NotCopy` which does implement the `Copy` trait -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/default-binding-modes-both-sides-independent.rs:44:9 | LL | ref a @ b => { | -----^^^- | | | - | | move out of `a` occurs here - | borrow of `a` occurs here + | | 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 From d2b88b7050b0e21b136022c4cfe8d352c1425588 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 2 Feb 2020 21:17:49 +0100 Subject: [PATCH 6/6] move_ref_pattern: test captures inside closure --- ...ve-ref-patterns-closure-captures-inside.rs | 122 ++++++ ...ef-patterns-closure-captures-inside.stderr | 404 ++++++++++++++++++ 2 files changed, 526 insertions(+) create mode 100644 src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs create mode 100644 src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.stderr diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs new file mode 100644 index 0000000000000..4c3ca62e16586 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs @@ -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` +} diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.stderr b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.stderr new file mode 100644 index 0000000000000..9159e3e221349 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.stderr @@ -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`.