Under the gate, `x @ Some(y)` is allowed.
This is subject to various restrictions for soundness.
/// Allows the use of `loop` and `while` in constants.
(active, const_loop, "1.41.0", Some(52000), None),
+ /// Allows bindings in the subpattern of a binding pattern.
+ /// For example, you can write `x @ Some(y)`.
+ (active, bindings_after_at, "1.41.0", Some(65490), None),
+
// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------
sym::or_patterns,
sym::let_chains,
sym::raw_dylib,
+ sym::bindings_after_at,
];
use super::{PatCtxt, PatKind, PatternError};
-use rustc::lint;
-use rustc::session::Session;
-use rustc::ty::subst::{InternalSubsts, SubstsRef};
-use rustc::ty::{self, Ty, TyCtxt};
-use rustc_errors::{Applicability, DiagnosticBuilder};
-
use rustc::hir::def::*;
use rustc::hir::def_id::DefId;
use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc::hir::HirId;
use rustc::hir::{self, Pat};
-
-use std::slice;
-
+use rustc::lint;
+use rustc::session::Session;
+use rustc::ty::subst::{InternalSubsts, SubstsRef};
+use rustc::ty::{self, Ty, TyCtxt};
+use rustc_error_codes::*;
+use rustc_errors::{Applicability, DiagnosticBuilder};
+use syntax::feature_gate::feature_err;
+use syntax_pos::symbol::sym;
use syntax_pos::{MultiSpan, Span};
-use rustc_error_codes::*;
+use std::slice;
crate fn check_match(tcx: TyCtxt<'_>, def_id: DefId) {
let body_id = match tcx.hir().as_local_hir_id(def_id) {
impl<'tcx> MatchVisitor<'_, 'tcx> {
fn check_patterns(&mut self, has_guard: bool, pat: &Pat) {
check_legality_of_move_bindings(self, has_guard, pat);
- check_legality_of_bindings_in_at_patterns(self, pat);
+ if !self.tcx.features().bindings_after_at {
+ check_legality_of_bindings_in_at_patterns(self, pat);
+ }
}
fn check_match(&mut self, scrut: &hir::Expr, arms: &'tcx [hir::Arm], source: hir::MatchSource) {
match pat.kind {
hir::PatKind::Binding(.., ref subpat) => {
if !self.bindings_allowed {
- struct_span_err!(
- self.cx.tcx.sess,
+ feature_err(
+ &self.cx.tcx.sess.parse_sess,
+ sym::bindings_after_at,
pat.span,
- E0303,
- "pattern bindings are not allowed after an `@`"
+ "pattern bindings after an `@` are unstable",
)
- .span_label(pat.span, "not allowed after `@`")
.emit();
}
if let PatKind::Ident(_, _, ref mut sub @ None) = rhs.kind {
// The user inverted the order, so help them fix that.
let mut applicability = Applicability::MachineApplicable;
+ // FIXME(bindings_after_at): Remove this code when stabilizing the feature.
lhs.walk(&mut |p| match p.kind {
// `check_match` is unhappy if the subpattern has a binding anywhere.
PatKind::Ident(..) => {
bench,
bin,
bind_by_move_pattern_guards,
+ bindings_after_at,
block,
bool,
borrowck_graphviz_postflow,
+#![feature(bindings_after_at)]
+//~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+
fn main() {
let x = Some("s".to_string());
match x {
op_string @ Some(s) => {},
//~^ ERROR E0007
- //~| ERROR E0303
//~| ERROR E0382
None => {},
}
-error[E0007]: cannot bind by-move with sub-bindings
- --> $DIR/E0007.rs:4:9
+warning: the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+ --> $DIR/E0007.rs:1:12
|
-LL | op_string @ Some(s) => {},
- | ^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
+LL | #![feature(bindings_after_at)]
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
-error[E0303]: pattern bindings are not allowed after an `@`
- --> $DIR/E0007.rs:4:26
+error[E0007]: cannot bind by-move with sub-bindings
+ --> $DIR/E0007.rs:7:9
|
LL | op_string @ Some(s) => {},
- | ^ not allowed after `@`
+ | ^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0382]: use of moved value
- --> $DIR/E0007.rs:4:26
+ --> $DIR/E0007.rs:7:26
|
LL | let x = Some("s".to_string());
| - move occurs because `x` has type `std::option::Option<std::string::String>`, which does not implement the `Copy` trait
| | value used here after move
| value moved here
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
-Some errors have detailed explanations: E0007, E0303, E0382.
+Some errors have detailed explanations: E0007, E0382.
For more information about an error, try `rustc --explain E0007`.
+++ /dev/null
-fn main() {
- match Some("hi".to_string()) {
- ref op_string_ref @ Some(s) => {},
- //~^ ERROR pattern bindings are not allowed after an `@` [E0303]
- //~| ERROR E0009
- None => {},
- }
-}
+++ /dev/null
-error[E0009]: cannot bind by-move and by-ref in the same pattern
- --> $DIR/E0303.rs:3:34
- |
-LL | ref op_string_ref @ Some(s) => {},
- | -------------------------^-
- | | |
- | | by-move pattern here
- | both by-ref and by-move used
-
-error[E0303]: pattern bindings are not allowed after an `@`
- --> $DIR/E0303.rs:3:34
- |
-LL | ref op_string_ref @ Some(s) => {},
- | ^ not allowed after `@`
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0009, E0303.
-For more information about an error, try `rustc --explain E0009`.
--- /dev/null
+#![feature(bindings_after_at)]
+//~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+
+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!()
+ }
+}
--- /dev/null
+warning: the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+ --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:1:12
+ |
+LL | #![feature(bindings_after_at)]
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+
+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:9:23
+ |
+LL | Some(ref _y @ _z) => { },
+ | ---------^^
+ | | |
+ | | by-move pattern here
+ | both by-ref and by-move used
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0009`.
--- /dev/null
+// See issue #12534.
+
+#![feature(bindings_after_at)]
+//~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+
+fn main() {}
+
+struct A(Box<u8>);
+
+fn f(a @ A(u): A) -> Box<u8> {
+ //~^ ERROR cannot bind by-move with sub-bindings
+ //~| ERROR use of moved value
+ drop(a);
+ u
+}
--- /dev/null
+warning: the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+ --> $DIR/bind-by-move-no-subbindings-fun-param.rs:3:12
+ |
+LL | #![feature(bindings_after_at)]
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0007]: cannot bind by-move with sub-bindings
+ --> $DIR/bind-by-move-no-subbindings-fun-param.rs:10:6
+ |
+LL | fn f(a @ A(u): A) -> Box<u8> {
+ | ^^^^^^^^ binds an already bound by-move value by moving it
+
+error[E0382]: use of moved value
+ --> $DIR/bind-by-move-no-subbindings-fun-param.rs:10:12
+ |
+LL | fn f(a @ A(u): A) -> Box<u8> {
+ | ------^-
+ | | |
+ | | value used here after move
+ | value moved here
+ | move occurs because value has type `A`, which does not implement the `Copy` trait
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0007, E0382.
+For more information about an error, try `rustc --explain E0007`.
--- /dev/null
+// Test that moving on both sides of an `@` pattern is not allowed.
+
+#![feature(bindings_after_at)]
+//~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+
+fn main() {
+ struct U; // Not copy!
+
+ let a @ b = U;
+ //~^ ERROR cannot bind by-move with sub-bindings
+ //~| ERROR use of moved value
+
+ let a @ (b, c) = (U, U);
+ //~^ ERROR cannot bind by-move with sub-bindings
+ //~| 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
+ }
+}
--- /dev/null
+warning: the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+ --> $DIR/borrowck-move-and-move.rs:3:12
+ |
+LL | #![feature(bindings_after_at)]
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0007]: cannot bind by-move with sub-bindings
+ --> $DIR/borrowck-move-and-move.rs:9: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:13: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:18: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:18:21
+ |
+LL | a @ Ok(b) | a @ Err(b) => {}
+ | ^^^^^^^^^^ binds an already bound by-move value by moving it
+
+error[E0382]: use of moved value
+ --> $DIR/borrowck-move-and-move.rs:9:13
+ |
+LL | let a @ b = U;
+ | ----^ - move occurs because value has type `main::U`, which does not implement the `Copy` trait
+ | | |
+ | | value used here after move
+ | value moved here
+
+error[E0382]: use of moved value
+ --> $DIR/borrowck-move-and-move.rs:13: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
+ | | |
+ | | value used here after move
+ | value moved here
+
+error[E0382]: use of moved value
+ --> $DIR/borrowck-move-and-move.rs:18:16
+ |
+LL | match Ok(U) {
+ | ----- move occurs because value has type `std::result::Result<main::U, main::U>`, which does not implement the `Copy` trait
+LL | a @ Ok(b) | a @ Err(b) => {}
+ | -------^-
+ | | |
+ | | value used here after move
+ | value moved here
+
+error[E0382]: use of moved value
+ --> $DIR/borrowck-move-and-move.rs:18:29
+ |
+LL | match Ok(U) {
+ | ----- move occurs because value has type `std::result::Result<main::U, main::U>`, which does not implement the `Copy` trait
+LL | a @ Ok(b) | a @ Err(b) => {}
+ | --------^-
+ | | |
+ | | value used here after move
+ | value moved here
+
+error: aborting due to 8 previous errors
+
+Some errors have detailed explanations: E0007, E0382.
+For more information about an error, try `rustc --explain E0007`.
--- /dev/null
+// Test `@` patterns combined with `box` patterns.
+
+#![feature(bindings_after_at)]
+//~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+#![feature(box_patterns)]
+
+#[derive(Copy, Clone)]
+struct C;
+
+fn main() {
+ let a @ box &b = Box::new(&C);
+ //~^ ERROR cannot bind by-move with sub-bindings
+ //~| 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
+
+ let ref a @ box b = Box::new(C); // OK; the type is `Copy`.
+ drop(b);
+ drop(b);
+ drop(a);
+
+ struct NC;
+
+ let ref a @ box b = Box::new(NC); //~ ERROR cannot bind by-move and by-ref in the same pattern
+
+ let ref a @ box ref b = Box::new(NC); // OK.
+ drop(a);
+ drop(b);
+
+ let ref a @ box ref mut b = Box::new(NC); // FIXME: This should not compile.
+ let ref a @ box ref mut b = Box::new(NC); // FIXME: This should not compile.
+ *b = NC;
+ let ref a @ box ref mut b = Box::new(NC);
+ //~^ 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 `_` as immutable because it is also borrowed as mutable
+ *a = Box::new(NC);
+ drop(b);
+}
--- /dev/null
+warning: the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+ --> $DIR/borrowck-pat-at-and-box.rs:3:12
+ |
+LL | #![feature(bindings_after_at)]
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0007]: cannot bind by-move with sub-bindings
+ --> $DIR/borrowck-pat-at-and-box.rs:11: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:15:9
+ |
+LL | let a @ box b = Box::new(C);
+ | ^^^^^^^^^ 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:26:21
+ |
+LL | let ref a @ box b = Box::new(NC);
+ | ------------^
+ | | |
+ | | by-move pattern here
+ | both by-ref and by-move used
+
+error[E0382]: use of moved value
+ --> $DIR/borrowck-pat-at-and-box.rs:11: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
+ | | |
+ | | value used here after move
+ | value moved here
+
+error[E0382]: use of moved value
+ --> $DIR/borrowck-pat-at-and-box.rs:15:17
+ |
+LL | let a @ box b = Box::new(C);
+ | --------^ ----------- move occurs because value has type `std::boxed::Box<C>`, which does not implement the `Copy` trait
+ | | |
+ | | 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:35:21
+ |
+LL | let ref a @ box ref mut b = Box::new(NC);
+ | ------------^^^^^^^^^
+ | | |
+ | | mutable borrow occurs here
+ | immutable borrow occurs here
+...
+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:40:25
+ |
+LL | let ref mut a @ box ref b = Box::new(NC);
+ | ----------------^^^^^
+ | | |
+ | | immutable borrow occurs here
+ | mutable borrow occurs here
+LL |
+LL | *a = Box::new(NC);
+ | -- mutable borrow later used here
+
+error: aborting due to 7 previous errors
+
+Some errors have detailed explanations: E0007, E0009, E0382, E0502.
+For more information about an error, try `rustc --explain E0007`.
--- /dev/null
+// check-pass
+
+// Test `Copy` bindings in the rhs of `@` patterns.
+
+#![feature(slice_patterns)]
+#![feature(bindings_after_at)]
+//~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+
+#[derive(Copy, Clone)]
+struct C;
+
+#[derive(Copy, Clone)]
+struct P<A, B>(A, B);
+
+enum E<A, B> { L(A), R(B) }
+
+fn main() {
+ let a @ b @ c @ d = C;
+ let a @ (b, c) = (C, C);
+ let a @ P(b, P(c, d)) = P(C, P(C, C));
+ let a @ [b, c] = [C, C];
+ let a @ [b, .., c] = [C, C, C];
+ let a @ &(b, c) = &(C, C);
+ let a @ &(b, &P(c, d)) = &(C, &P(C, C));
+
+ use self::E::*;
+ match L(C) {
+ L(a) | R(a) => {
+ let a: C = a;
+ drop(a);
+ drop(a);
+ }
+ }
+ match R(&L(&C)) {
+ L(L(&a)) | L(R(&a)) | R(L(&a)) | R(R(&a)) => {
+ let a: C = a;
+ drop(a);
+ drop(a);
+ }
+ }
+}
--- /dev/null
+warning: the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+ --> $DIR/borrowck-pat-by-copy-bindings-in-at.rs:6:12
+ |
+LL | #![feature(bindings_after_at)]
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+
--- /dev/null
+#![feature(bindings_after_at)]
+//~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+
+fn main() {
+ match Some("hi".to_string()) {
+ ref op_string_ref @ Some(s) => {},
+ //~^ ERROR E0009
+ None => {},
+ }
+}
--- /dev/null
+warning: the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+ --> $DIR/borrowck-pat-by-move-and-ref.rs:1:12
+ |
+LL | #![feature(bindings_after_at)]
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0009]: cannot bind by-move and by-ref in the same pattern
+ --> $DIR/borrowck-pat-by-move-and-ref.rs:6:34
+ |
+LL | ref op_string_ref @ Some(s) => {},
+ | -------------------------^-
+ | | |
+ | | by-move pattern here
+ | both by-ref and by-move used
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0009`.
--- /dev/null
+// check-pass
+
+// Test that `ref` patterns may be used on both sides
+// of an `@` pattern according to NLL borrowck.
+
+#![feature(bindings_after_at)]
+//~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+
+fn main() {
+ struct U; // Not copy!
+
+ let ref a @ ref b = U;
+ let _: &U = a;
+ let _: &U = b;
+
+ let ref a @ (ref b, [ref c, ref d]) = (U, [U, U]);
+ let _: &(U, [U; 2]) = a;
+ let _: &U = b;
+ let _: &U = c;
+ let _: &U = d;
+
+ let a @ (b, [c, d]) = &(U, [U, U]);
+ let _: &(U, [U; 2]) = a;
+ let _: &U = b;
+ let _: &U = c;
+ let _: &U = d;
+
+ let ref a @ &ref b = &U;
+ let _: &&U = a;
+ let _: &U = b;
+
+ match Ok(U) {
+ ref a @ Ok(ref b) | ref a @ Err(ref b) => {
+ let _: &Result<U, U> = a;
+ let _: &U = b;
+ }
+ }
+}
--- /dev/null
+warning: the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+ --> $DIR/borrowck-pat-ref-both-sides.rs:6:12
+ |
+LL | #![feature(bindings_after_at)]
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+
--- /dev/null
+#![feature(bindings_after_at)]
+//~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+
+enum Option<T> {
+ None,
+ Some(T),
+}
+
+fn main() {
+ match &mut Some(1) {
+ ref mut z @ &mut Some(ref a) => {
+ //~^ ERROR cannot borrow `_` as immutable because it is also borrowed as mutable
+ **z = None;
+ println!("{}", *a);
+ }
+ _ => ()
+ }
+
+ struct U;
+
+ let ref a @ ref mut b = U; // FIXME: This should not compile.
+ let ref mut a @ ref b = U; // FIXME: This should not compile.
+ let ref a @ (ref mut b, ref mut c) = (U, U); // FIXME: This should not compile.
+ let ref mut a @ (ref b, ref c) = (U, U); // FIXME: This should not compile.
+
+ // FIXME: Seems like we have a soundness hole here.
+ let ref mut a @ ref b = U;
+ *a = U; // We are mutating...
+ drop(b); // ..but at the same time we are holding a live shared borrow.
+ // FIXME: Inverted; seems like the same issue exists here as well.
+ let ref a @ ref mut b = U;
+ *b = U;
+ drop(a);
+
+ match Ok(U) {
+ ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => {
+ *a = Err(U); // FIXME: ^ should not compile.
+ drop(b);
+ }
+ }
+
+ match Ok(U) {
+ ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
+ //~^ 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);
+ }
+ }
+
+ match Ok(U) {
+ ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
+ //~^ 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 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 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 move out of `a` in pattern guard
+ _ => {}
+ }
+
+ let ref a @ (ref mut b, ref mut c) = (U, U);
+ *b = U; // FIXME: ^ should not compile.
+ *c = U;
+
+ let ref a @ (ref mut b, ref mut c) = (U, U);
+ //~^ 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);
+ *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); // FIXME: This should not compile.
+}
--- /dev/null
+warning: the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:1:12
+ |
+LL | #![feature(bindings_after_at)]
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:31
+ |
+LL | ref mut z @ &mut Some(ref a) => {
+ | ----------------------^^^^^-
+ | | |
+ | | immutable borrow occurs here
+ | mutable borrow occurs here
+LL |
+LL | **z = None;
+ | ---------- 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:43:20
+ |
+LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
+ | -----------^^^^^^^^^-
+ | | |
+ | | mutable borrow occurs here
+ | immutable borrow occurs here
+...
+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:43:45
+ |
+LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
+ | ------------^^^^^^^^^-
+ | | |
+ | | mutable borrow occurs here
+ | immutable borrow occurs here
+...
+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:52:61
+ |
+LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
+ | ^^^^^^ cannot assign
+ |
+ = 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:57:61
+ |
+LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
+ | ^^^^^^^^^^^ cannot assign
+ |
+ = 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:62: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
+ |
+ = 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:67:66
+ |
+LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
+ | ^ move occurs because `a` has type `&mut std::result::Result<main::U, main::U>`, which does not implement the `Copy` trait
+ |
+ = 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:76:18
+ |
+LL | let ref a @ (ref mut b, ref mut c) = (U, U);
+ | ---------^^^^^^^^^------------
+ | | |
+ | | mutable borrow occurs here
+ | immutable borrow occurs here
+...
+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:76:29
+ |
+LL | let ref a @ (ref mut b, ref mut c) = (U, U);
+ | --------------------^^^^^^^^^-
+ | | |
+ | | mutable borrow occurs here
+ | immutable borrow occurs here
+...
+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:82:18
+ |
+LL | let ref a @ (ref mut b, ref mut c) = (U, U);
+ | ---------^^^^^^^^^------------
+ | | |
+ | | mutable borrow occurs here
+ | immutable borrow occurs here
+...
+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:82:29
+ |
+LL | let ref a @ (ref mut b, ref mut c) = (U, U);
+ | --------------------^^^^^^^^^-
+ | | |
+ | | mutable borrow occurs here
+ | immutable borrow occurs here
+...
+LL | drop(a);
+ | - immutable borrow later used here
+
+error: aborting due to 11 previous errors
+
+Some errors have detailed explanations: E0502, E0507.
+For more information about an error, try `rustc --explain E0502`.
--- /dev/null
+// Test that `ref mut x @ ref mut y` and varieties of that are not allowed.
+
+#![feature(bindings_after_at)]
+//~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+
+fn main() {
+ struct U;
+
+ let ref mut a @ ref mut b = U;
+ //~^ ERROR cannot borrow `_` as mutable more than once at a time
+ drop(a);
+ let ref mut a @ ref mut b = U; // FIXME: This should not compile.
+ drop(b);
+ let ref mut a @ ref mut b = U; // FIXME: This should not compile.
+
+ let ref mut a @ ref mut b = U;
+ //~^ ERROR cannot borrow `_` as mutable more than once at a time
+ *a = U;
+ let ref mut a @ ref mut b = U; // FIXME: This should not compile.
+ *b = U;
+
+ let ref mut a @ (ref mut b, [ref mut c, ref mut d]) = (U, [U, U]);
+ // FIXME: This should not compile.
+
+ let a @ (ref mut b, ref mut c) = (U, U);
+ //~^ ERROR cannot bind by-move with sub-bindings
+ //~| 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
+
+ let a @ &mut ref mut b = &mut U;
+ //~^ ERROR cannot bind by-move with sub-bindings
+ //~| 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
+
+ match Ok(U) {
+ ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
+ // FIXME: This should not compile.
+ }
+ }
+ match Ok(U) {
+ ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
+ *b = U;
+ // FIXME: This should not compile.
+ }
+ }
+ match Ok(U) {
+ ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
+ //~^ 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);
+
+ // FIXME: The binding name `_` used above makes for problematic diagnostics.
+ // Resolve that somehow...
+ }
+ }
+ match Ok(U) {
+ ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
+ //~^ ERROR cannot borrow `_` as mutable more than once at a time
+ //~| ERROR cannot borrow `_` as mutable more than once at a time
+ drop(a);
+ }
+ }
+}
--- /dev/null
+warning: the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:3:12
+ |
+LL | #![feature(bindings_after_at)]
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0007]: cannot bind by-move with sub-bindings
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:25:9
+ |
+LL | let a @ (ref mut b, ref mut c) = (U, U);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
+
+error[E0007]: cannot bind by-move with sub-bindings
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:29:9
+ |
+LL | let a @ (b, [c, d]) = &mut val; // Same as ^--
+ | ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
+
+error[E0007]: cannot bind by-move with sub-bindings
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:33:9
+ |
+LL | let a @ &mut ref mut b = &mut U;
+ | ^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
+
+error[E0007]: cannot bind by-move with sub-bindings
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:36:9
+ |
+LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
+
+error[E0499]: cannot borrow `_` as mutable more than once at a time
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:9:21
+ |
+LL | let ref mut a @ ref mut b = U;
+ | ------------^^^^^^^^^
+ | | |
+ | | second mutable borrow occurs here
+ | first mutable borrow occurs here
+LL |
+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:16:21
+ |
+LL | let ref mut a @ ref mut b = U;
+ | ------------^^^^^^^^^
+ | | |
+ | | second mutable borrow occurs here
+ | first mutable borrow occurs here
+LL |
+LL | *a = U;
+ | ------ first borrow later used here
+
+error[E0382]: borrow of moved value
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:25: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
+ | | |
+ | | value borrowed here after move
+ | value moved here
+
+error[E0382]: borrow of moved value
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:29: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
+ | | |
+ | | value borrowed here after move
+ | value moved here
+
+error[E0382]: borrow of moved value
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:33: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
+ | | |
+ | | value borrowed here after move
+ | value moved here
+
+error[E0382]: borrow of moved value
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:36: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
+ | | |
+ | | value borrowed here after move
+ | value moved here
+
+error[E0499]: cannot borrow `_` as mutable more than once at a time
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:52:24
+ |
+LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
+ | ---------------^^^^^^^^^-
+ | | |
+ | | second mutable borrow occurs here
+ | first mutable borrow occurs here
+...
+LL | *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:52:53
+ |
+LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
+ | ----------------^^^^^^^^^-
+ | | |
+ | | second mutable borrow occurs here
+ | first mutable borrow occurs here
+...
+LL | *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:62:24
+ |
+LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
+ | ---------------^^^^^^^^^-
+ | | |
+ | | second mutable borrow occurs here
+ | first mutable borrow occurs here
+...
+LL | drop(a);
+ | - first borrow later used here
+
+error[E0499]: cannot borrow `_` as mutable more than once at a time
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:62:53
+ |
+LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
+ | ----------------^^^^^^^^^-
+ | | |
+ | | second mutable borrow occurs here
+ | first mutable borrow occurs here
+...
+LL | drop(a);
+ | - first borrow later used here
+
+error: aborting due to 14 previous errors
+
+Some errors have detailed explanations: E0007, E0382, E0499.
+For more information about an error, try `rustc --explain E0007`.
--- /dev/null
+// Test that mixing `Copy` and non-`Copy` types in `@` patterns is forbidden.
+
+#![feature(bindings_after_at)]
+//~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+
+#[derive(Copy, Clone)]
+struct C;
+
+struct NC<A, B>(A, B);
+
+fn main() {
+ let a @ NC(b, c) = NC(C, C);
+ //~^ ERROR cannot bind by-move with sub-bindings
+ //~| ERROR use of moved value
+
+ 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
+}
--- /dev/null
+warning: the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+ --> $DIR/copy-and-move-mixed.rs:3:12
+ |
+LL | #![feature(bindings_after_at)]
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0007]: cannot bind by-move with sub-bindings
+ --> $DIR/copy-and-move-mixed.rs:12: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:16: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:16: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:12:19
+ |
+LL | let a @ NC(b, c) = NC(C, C);
+ | ----------^- -------- move occurs because value has type `NC<C, C>`, which does not implement the `Copy` trait
+ | | |
+ | | value used here after move
+ | value moved here
+
+error[E0382]: use of moved value
+ --> $DIR/copy-and-move-mixed.rs:16:19
+ |
+LL | let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C));
+ | ----------^^^^^^^^^^^^- --------------- move occurs because value has type `NC<C, NC<C, C>>`, which does not implement the `Copy` trait
+ | | |
+ | | value used here after move
+ | value moved here
+
+error[E0382]: use of moved value
+ --> $DIR/copy-and-move-mixed.rs:16:29
+ |
+LL | let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C));
+ | ----------^-
+ | | |
+ | | value used here after move
+ | value moved here
+ |
+ = note: move occurs because value has type `NC<C, C>`, which does not implement the `Copy` trait
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0007, E0382.
+For more information about an error, try `rustc --explain E0007`.
--- /dev/null
+// Ensures the independence of each side in `binding @ subpat`
+// determine their binding modes independently of each other.
+//
+// That is, `binding` does not influence `subpat`.
+// This is important because we might want to allow `p1 @ p2`,
+// where both `p1` and `p2` are syntactically unrestricted patterns.
+// If `binding` is allowed to influence `subpat`,
+// this would create problems for the generalization aforementioned.
+
+#![feature(bindings_after_at)]
+//~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+
+fn main() {
+ struct NotCopy;
+
+ let a @ b = &NotCopy; // OK
+ let _: &NotCopy = a;
+ 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
+ match Ok(NotCopy) {
+ Ok(ref a @ b) | Err(ref a @ b) => {}
+ //~^ ERROR cannot bind by-move and by-ref in the same pattern
+ }
+ match NotCopy {
+ ref a @ b => {}
+ //~^ ERROR cannot bind by-move and by-ref in the same pattern
+ }
+}
--- /dev/null
+warning: the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+ --> $DIR/default-binding-modes-both-sides-independent.rs:10:12
+ |
+LL | #![feature(bindings_after_at)]
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0009]: cannot bind by-move and by-ref in the same pattern
+ --> $DIR/default-binding-modes-both-sides-independent.rs:21:17
+ |
+LL | let ref a @ b = NotCopy;
+ | --------^
+ | | |
+ | | by-move pattern here
+ | both by-ref and by-move used
+
+error[E0009]: cannot bind by-move and by-ref in the same pattern
+ --> $DIR/default-binding-modes-both-sides-independent.rs:22:21
+ |
+LL | let ref mut a @ b = NotCopy;
+ | ------------^
+ | | |
+ | | by-move pattern here
+ | both by-ref and by-move used
+
+error[E0009]: cannot bind by-move and by-ref in the same pattern
+ --> $DIR/default-binding-modes-both-sides-independent.rs:24:20
+ |
+LL | Ok(ref a @ b) | Err(ref a @ b) => {}
+ | ^ --------^
+ | | | |
+ | | | by-move pattern here
+ | | both by-ref and by-move used
+ | by-move pattern here
+
+error[E0009]: cannot bind by-move and by-ref in the same pattern
+ --> $DIR/default-binding-modes-both-sides-independent.rs:28:17
+ |
+LL | ref a @ b => {}
+ | --------^
+ | | |
+ | | by-move pattern here
+ | both by-ref and by-move used
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0009`.
--- /dev/null
+fn main() {
+ let x @ y = 0; //~ ERROR pattern bindings after an `@` are unstable
+}
--- /dev/null
+error[E0658]: pattern bindings after an `@` are unstable
+ --> $DIR/feature-gate-bindings_after_at.rs:2:13
+ |
+LL | let x @ y = 0;
+ | ^
+ |
+ = note: for more information, see https://github.com/rust-lang/rust/issues/65490
+ = help: add `#![feature(bindings_after_at)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
--- /dev/null
+// run-pass
+
+#![feature(bindings_after_at)]
+//~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+
+struct A { a: u8, b: u8 }
+
+pub fn main() {
+ match (A { a: 10, b: 20 }) {
+ ref x @ A { ref a, b: 20 } => {
+ assert_eq!(x.a, 10);
+ assert_eq!(*a, 10);
+ }
+ A { b: ref _b, .. } => panic!(),
+ }
+}
--- /dev/null
+warning: the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+ --> $DIR/nested-patterns.rs:3:12
+ |
+LL | #![feature(bindings_after_at)]
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+
--- /dev/null
+// Test that `binding @ subpat` acts as a product context with respect to duplicate binding names.
+// The code that is tested here lives in resolve (see `resolve_pattern_inner`).
+
+#![feature(bindings_after_at)]
+//~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+#![feature(or_patterns)]
+//~^ WARN the feature `or_patterns` is incomplete and may cause the compiler to crash
+
+fn main() {
+ let a @ a @ a = ();
+ //~^ ERROR identifier `a` is bound more than once in the same pattern
+ //~| ERROR identifier `a` is bound more than once in the same pattern
+ let ref a @ ref a = ();
+ //~^ ERROR identifier `a` is bound more than once in the same pattern
+ let ref mut a @ ref mut a = ();
+ //~^ ERROR identifier `a` is bound more than once in the same pattern
+
+ let a @ (Ok(a) | Err(a)) = Ok(());
+ //~^ ERROR identifier `a` is bound more than once in the same pattern
+ //~| ERROR identifier `a` is bound more than once in the same pattern
+}
--- /dev/null
+error[E0416]: identifier `a` is bound more than once in the same pattern
+ --> $DIR/pat-at-same-name-both.rs:10:13
+ |
+LL | let a @ a @ a = ();
+ | ^ used in a pattern more than once
+
+error[E0416]: identifier `a` is bound more than once in the same pattern
+ --> $DIR/pat-at-same-name-both.rs:10:17
+ |
+LL | let a @ a @ a = ();
+ | ^ used in a pattern more than once
+
+error[E0416]: identifier `a` is bound more than once in the same pattern
+ --> $DIR/pat-at-same-name-both.rs:13:21
+ |
+LL | let ref a @ ref a = ();
+ | ^ used in a pattern more than once
+
+error[E0416]: identifier `a` is bound more than once in the same pattern
+ --> $DIR/pat-at-same-name-both.rs:15:29
+ |
+LL | let ref mut a @ ref mut a = ();
+ | ^ used in a pattern more than once
+
+error[E0416]: identifier `a` is bound more than once in the same pattern
+ --> $DIR/pat-at-same-name-both.rs:18:17
+ |
+LL | let a @ (Ok(a) | Err(a)) = Ok(());
+ | ^ used in a pattern more than once
+
+error[E0416]: identifier `a` is bound more than once in the same pattern
+ --> $DIR/pat-at-same-name-both.rs:18:26
+ |
+LL | let a @ (Ok(a) | Err(a)) = Ok(());
+ | ^ used in a pattern more than once
+
+warning: the feature `bindings_after_at` is incomplete and may cause the compiler to crash
+ --> $DIR/pat-at-same-name-both.rs:4:12
+ |
+LL | #![feature(bindings_after_at)]
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: the feature `or_patterns` is incomplete and may cause the compiler to crash
+ --> $DIR/pat-at-same-name-both.rs:6:12
+ |
+LL | #![feature(or_patterns)]
+ | ^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0416`.
+++ /dev/null
-enum Option<T> {
- None,
- Some(T),
-}
-
-fn main() {
- match &mut Some(1) {
- ref mut z @ &mut Some(ref a) => {
- //~^ ERROR pattern bindings are not allowed after an `@`
- //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable
- **z = None;
- println!("{}", *a);
- }
- _ => ()
- }
-}
+++ /dev/null
-error[E0303]: pattern bindings are not allowed after an `@`
- --> $DIR/pattern-bindings-after-at.rs:8:31
- |
-LL | ref mut z @ &mut Some(ref a) => {
- | ^^^^^ not allowed after `@`
-
-error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable
- --> $DIR/pattern-bindings-after-at.rs:8:31
- |
-LL | ref mut z @ &mut Some(ref a) => {
- | ----------------------^^^^^-
- | | |
- | | immutable borrow occurs here
- | mutable borrow occurs here
-...
-LL | **z = None;
- | ---------- mutable borrow later used here
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0303, E0502.
-For more information about an error, try `rustc --explain E0303`.