Introduce #![feature(bindings_after_at)]
.
Under the gate, `x @ Some(y)` is allowed. This is subject to various restrictions for soundness.
This commit is contained in:
parent
a916ac22b9
commit
5f92a56ed6
38 changed files with 1156 additions and 92 deletions
|
@ -539,6 +539,10 @@ declare_features! (
|
|||
/// 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
|
||||
// -------------------------------------------------------------------------
|
||||
|
@ -554,4 +558,5 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
|
|||
sym::or_patterns,
|
||||
sym::let_chains,
|
||||
sym::raw_dylib,
|
||||
sym::bindings_after_at,
|
||||
];
|
||||
|
|
|
@ -4,23 +4,22 @@ use super::_match::{expand_pattern, is_useful, MatchCheckCtxt, Matrix, PatStack}
|
|||
|
||||
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) {
|
||||
|
@ -123,7 +122,9 @@ 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_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) {
|
||||
|
@ -656,13 +657,12 @@ impl<'v> Visitor<'v> for AtBindingPatternVisitor<'_, '_, '_> {
|
|||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -406,6 +406,7 @@ impl<'a> Parser<'a> {
|
|||
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(..) => {
|
||||
|
|
|
@ -165,6 +165,7 @@ symbols! {
|
|||
bench,
|
||||
bin,
|
||||
bind_by_move_pattern_guards,
|
||||
bindings_after_at,
|
||||
block,
|
||||
bool,
|
||||
borrowck_graphviz_postflow,
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
#![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 => {},
|
||||
}
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
warning: the feature `bindings_after_at` is incomplete and may cause the compiler to crash
|
||||
--> $DIR/E0007.rs:1:12
|
||||
|
|
||||
LL | #![feature(bindings_after_at)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error[E0007]: cannot bind by-move with sub-bindings
|
||||
--> $DIR/E0007.rs:4:9
|
||||
--> $DIR/E0007.rs:7:9
|
||||
|
|
||||
LL | op_string @ Some(s) => {},
|
||||
| ^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
|
||||
|
||||
error[E0303]: pattern bindings are not allowed after an `@`
|
||||
--> $DIR/E0007.rs:4:26
|
||||
|
|
||||
LL | op_string @ Some(s) => {},
|
||||
| ^ not allowed after `@`
|
||||
|
||||
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
|
||||
|
@ -22,7 +24,7 @@ LL | op_string @ Some(s) => {},
|
|||
| | 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`.
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
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 => {},
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
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`.
|
|
@ -0,0 +1,12 @@
|
|||
#![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!()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
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`.
|
|
@ -0,0 +1,15 @@
|
|||
// 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
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
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`.
|
|
@ -0,0 +1,24 @@
|
|||
// 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
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
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`.
|
|
@ -0,0 +1,44 @@
|
|||
// 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);
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
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`.
|
|
@ -0,0 +1,41 @@
|
|||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#![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 => {},
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
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`.
|
|
@ -0,0 +1,38 @@
|
|||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
#![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.
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
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`.
|
|
@ -0,0 +1,68 @@
|
|||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
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`.
|
21
src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs
Normal file
21
src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
// 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
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
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`.
|
|
@ -0,0 +1,31 @@
|
|||
// 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
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
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`.
|
|
@ -0,0 +1,3 @@
|
|||
fn main() {
|
||||
let x @ y = 0; //~ ERROR pattern bindings after an `@` are unstable
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
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`.
|
16
src/test/ui/pattern/bindings-after-at/nested-patterns.rs
Normal file
16
src/test/ui/pattern/bindings-after-at/nested-patterns.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
// 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!(),
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// 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
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
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`.
|
|
@ -1,16 +0,0 @@
|
|||
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);
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
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`.
|
Loading…
Add table
Reference in a new issue