From 5f92a56ed69d9384429353b713d74f67ee8f957c Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 11 Nov 2019 11:39:52 +0100 Subject: [PATCH 01/17] Introduce `#![feature(bindings_after_at)]`. Under the gate, `x @ Some(y)` is allowed. This is subject to various restrictions for soundness. --- src/librustc_feature/active.rs | 5 + src/librustc_mir/hair/pattern/check_match.rs | 32 ++-- src/librustc_parse/parser/pat.rs | 1 + src/libsyntax_pos/symbol.rs | 1 + src/test/ui/error-codes/E0007.rs | 4 +- src/test/ui/error-codes/E0007.stderr | 22 +-- src/test/ui/error-codes/E0303.rs | 8 - src/test/ui/error-codes/E0303.stderr | 19 --- ...her-can-live-while-the-other-survives-1.rs | 12 ++ ...can-live-while-the-other-survives-1.stderr | 20 +++ .../bind-by-move-no-subbindings-fun-param.rs | 15 ++ ...nd-by-move-no-subbindings-fun-param.stderr | 28 ++++ .../borrowck-move-and-move.rs | 24 +++ .../borrowck-move-and-move.stderr | 76 +++++++++ .../borrowck-pat-at-and-box.rs | 44 ++++++ .../borrowck-pat-at-and-box.stderr | 75 +++++++++ .../borrowck-pat-by-copy-bindings-in-at.rs | 41 +++++ ...borrowck-pat-by-copy-bindings-in-at.stderr | 8 + .../borrowck-pat-by-move-and-ref.rs | 10 ++ .../borrowck-pat-by-move-and-ref.stderr | 20 +++ .../borrowck-pat-ref-both-sides.rs | 38 +++++ .../borrowck-pat-ref-both-sides.stderr | 8 + .../borrowck-pat-ref-mut-and-ref.rs | 87 +++++++++++ .../borrowck-pat-ref-mut-and-ref.stderr | 128 ++++++++++++++++ .../borrowck-pat-ref-mut-twice.rs | 68 +++++++++ .../borrowck-pat-ref-mut-twice.stderr | 144 ++++++++++++++++++ .../bindings-after-at/copy-and-move-mixed.rs | 21 +++ .../copy-and-move-mixed.stderr | 59 +++++++ ...lt-binding-modes-both-sides-independent.rs | 31 ++++ ...inding-modes-both-sides-independent.stderr | 48 ++++++ .../feature-gate-bindings_after_at.rs | 3 + .../feature-gate-bindings_after_at.stderr | 12 ++ .../bindings-after-at/nested-patterns.rs | 16 ++ .../bindings-after-at/nested-patterns.stderr | 8 + .../pat-at-same-name-both.rs | 21 +++ .../pat-at-same-name-both.stderr | 53 +++++++ .../ui/pattern/pattern-bindings-after-at.rs | 16 -- .../pattern/pattern-bindings-after-at.stderr | 22 --- 38 files changed, 1156 insertions(+), 92 deletions(-) delete mode 100644 src/test/ui/error-codes/E0303.rs delete mode 100644 src/test/ui/error-codes/E0303.stderr create mode 100644 src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs create mode 100644 src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr create mode 100644 src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs create mode 100644 src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.stderr create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.stderr create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr create mode 100644 src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs create mode 100644 src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr create mode 100644 src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs create mode 100644 src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr create mode 100644 src/test/ui/pattern/bindings-after-at/feature-gate-bindings_after_at.rs create mode 100644 src/test/ui/pattern/bindings-after-at/feature-gate-bindings_after_at.stderr create mode 100644 src/test/ui/pattern/bindings-after-at/nested-patterns.rs create mode 100644 src/test/ui/pattern/bindings-after-at/nested-patterns.stderr create mode 100644 src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.rs create mode 100644 src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr delete mode 100644 src/test/ui/pattern/pattern-bindings-after-at.rs delete mode 100644 src/test/ui/pattern/pattern-bindings-after-at.stderr diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index a386cbf56af85..06dbc8faf1dab 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -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, ]; diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 4ebf41fb9d21f..a740b507b3a16 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -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(); } diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs index 9b5bf7e2378f5..1540e6d7c053f 100644 --- a/src/librustc_parse/parser/pat.rs +++ b/src/librustc_parse/parser/pat.rs @@ -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(..) => { diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 7e0308ee356df..8fdc199d9ed7c 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -165,6 +165,7 @@ symbols! { bench, bin, bind_by_move_pattern_guards, + bindings_after_at, block, bool, borrowck_graphviz_postflow, diff --git a/src/test/ui/error-codes/E0007.rs b/src/test/ui/error-codes/E0007.rs index cdda735ba4435..4f7fc0dc2326c 100644 --- a/src/test/ui/error-codes/E0007.rs +++ b/src/test/ui/error-codes/E0007.rs @@ -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 => {}, } diff --git a/src/test/ui/error-codes/E0007.stderr b/src/test/ui/error-codes/E0007.stderr index 89a6298c8752f..d7b8050c3a4cd 100644 --- a/src/test/ui/error-codes/E0007.stderr +++ b/src/test/ui/error-codes/E0007.stderr @@ -1,17 +1,19 @@ -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`, 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`. diff --git a/src/test/ui/error-codes/E0303.rs b/src/test/ui/error-codes/E0303.rs deleted file mode 100644 index 0530d43b653f5..0000000000000 --- a/src/test/ui/error-codes/E0303.rs +++ /dev/null @@ -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 => {}, - } -} diff --git a/src/test/ui/error-codes/E0303.stderr b/src/test/ui/error-codes/E0303.stderr deleted file mode 100644 index af537ce5625ca..0000000000000 --- a/src/test/ui/error-codes/E0303.stderr +++ /dev/null @@ -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`. 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 new file mode 100644 index 0000000000000..53d16e7ad3ec7 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs @@ -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!() + } +} 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 new file mode 100644 index 0000000000000..c4afdc576a16a --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr @@ -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`. 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 new file mode 100644 index 0000000000000..bfaab69a776b6 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs @@ -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); + +fn f(a @ A(u): A) -> Box { + //~^ ERROR cannot bind by-move with sub-bindings + //~| 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 new file mode 100644 index 0000000000000..15b0d5e2cb448 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr @@ -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 { + | ^^^^^^^^ 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 { + | ------^- + | | | + | | 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`. 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 new file mode 100644 index 0000000000000..e18d3bc06a933 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs @@ -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 + } +} 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 new file mode 100644 index 0000000000000..0b69ff0b8392c --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr @@ -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`, 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`, 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`. 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 new file mode 100644 index 0000000000000..4d94d94ae0e18 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs @@ -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); +} 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 new file mode 100644 index 0000000000000..fbf9dfff7feec --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr @@ -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`, 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`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs new file mode 100644 index 0000000000000..1115dd5b5a289 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs @@ -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); + +enum E { 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); + } + } +} diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.stderr new file mode 100644 index 0000000000000..e5bbc112bb138 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.stderr @@ -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 + 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 new file mode 100644 index 0000000000000..4b7f61c365e34 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs @@ -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 => {}, + } +} 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 new file mode 100644 index 0000000000000..9c8a4e25fb844 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr @@ -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`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs new file mode 100644 index 0000000000000..5fbedd02d25e5 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs @@ -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 = a; + let _: &U = b; + } + } +} diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.stderr new file mode 100644 index 0000000000000..7a500df77cd89 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.stderr @@ -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 + 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 new file mode 100644 index 0000000000000..3ea3d93f862f5 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs @@ -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 { + 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. +} 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 new file mode 100644 index 0000000000000..ce79b562ec99b --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr @@ -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`, 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`. 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 new file mode 100644 index 0000000000000..482fa0497f571 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs @@ -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); + } + } +} 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 new file mode 100644 index 0000000000000..c9bfba867787e --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr @@ -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`. 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 new file mode 100644 index 0000000000000..b517ed71c7344 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs @@ -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); + +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 +} 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 new file mode 100644 index 0000000000000..89993a48e193e --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr @@ -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`, 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>`, 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`, 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`. 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 new file mode 100644 index 0000000000000..df2efd08b9b25 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs @@ -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 + } +} 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 new file mode 100644 index 0000000000000..bb0d893887e29 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr @@ -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`. diff --git a/src/test/ui/pattern/bindings-after-at/feature-gate-bindings_after_at.rs b/src/test/ui/pattern/bindings-after-at/feature-gate-bindings_after_at.rs new file mode 100644 index 0000000000000..d655f15af1eba --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/feature-gate-bindings_after_at.rs @@ -0,0 +1,3 @@ +fn main() { + let x @ y = 0; //~ ERROR pattern bindings after an `@` are unstable +} diff --git a/src/test/ui/pattern/bindings-after-at/feature-gate-bindings_after_at.stderr b/src/test/ui/pattern/bindings-after-at/feature-gate-bindings_after_at.stderr new file mode 100644 index 0000000000000..5408f6b5fb56d --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/feature-gate-bindings_after_at.stderr @@ -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`. diff --git a/src/test/ui/pattern/bindings-after-at/nested-patterns.rs b/src/test/ui/pattern/bindings-after-at/nested-patterns.rs new file mode 100644 index 0000000000000..63e07842b1ab0 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/nested-patterns.rs @@ -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!(), + } +} diff --git a/src/test/ui/pattern/bindings-after-at/nested-patterns.stderr b/src/test/ui/pattern/bindings-after-at/nested-patterns.stderr new file mode 100644 index 0000000000000..1864a8e2af733 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/nested-patterns.stderr @@ -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 + diff --git a/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.rs b/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.rs new file mode 100644 index 0000000000000..2b5528f49a6bb --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.rs @@ -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 +} diff --git a/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr b/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr new file mode 100644 index 0000000000000..92a97becc8424 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr @@ -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`. diff --git a/src/test/ui/pattern/pattern-bindings-after-at.rs b/src/test/ui/pattern/pattern-bindings-after-at.rs deleted file mode 100644 index aff7264752de2..0000000000000 --- a/src/test/ui/pattern/pattern-bindings-after-at.rs +++ /dev/null @@ -1,16 +0,0 @@ -enum Option { - 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); - } - _ => () - } -} diff --git a/src/test/ui/pattern/pattern-bindings-after-at.stderr b/src/test/ui/pattern/pattern-bindings-after-at.stderr deleted file mode 100644 index 35ee7877f2f78..0000000000000 --- a/src/test/ui/pattern/pattern-bindings-after-at.stderr +++ /dev/null @@ -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`. From 25b6a28a51e1539abd1df3c1ca6371d0873f8d6d Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 14 Dec 2019 17:43:48 +0100 Subject: [PATCH 02/17] add a fixme --- src/librustc_mir/hair/pattern/check_match.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index a740b507b3a16..0094a6ed7e5c3 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -281,6 +281,7 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pa variant.ident == ident && variant.ctor_kind == CtorKind::Const }) { + // FIXME(Centril): Should be a lint? let ty_path = cx.tcx.def_path_str(edef.did); let mut err = struct_span_warn!( cx.tcx.sess, From 6a87f99620f0883f9cf5924885c6175e578da6d6 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 14 Dec 2019 18:20:13 +0100 Subject: [PATCH 03/17] check_legality_of_move_bindings: generalize diagnostics & add comments --- src/librustc_mir/hair/pattern/check_match.rs | 24 ++++++++++--------- ...can-live-while-the-other-survives-2.stderr | 2 +- ...can-live-while-the-other-survives-3.stderr | 2 +- ...can-live-while-the-other-survives-4.stderr | 2 +- src/test/ui/error-codes/E0009.stderr | 2 +- src/test/ui/issues/issue-53840.stderr | 4 ++-- ...can-live-while-the-other-survives-1.stderr | 2 +- .../borrowck-pat-at-and-box.stderr | 2 +- .../borrowck-pat-by-move-and-ref.stderr | 2 +- .../borrowck-pat-ref-mut-and-ref.stderr | 2 +- ...inding-modes-both-sides-independent.stderr | 17 ++++++------- .../rfc-2005-default-binding-mode/for.stderr | 2 +- 12 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 0094a6ed7e5c3..c3768e7438597 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -579,18 +579,20 @@ fn maybe_point_at_variant(ty: Ty<'_>, patterns: &[super::Pat<'_>]) -> Vec // Check the legality of legality of by-move bindings. fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: bool, pat: &Pat) { - let mut by_ref_span = None; + // Find all by-ref spans. + let mut by_ref_spans = Vec::new(); pat.each_binding(|_, hir_id, span, _| { if let Some(&bm) = cx.tables.pat_binding_modes().get(hir_id) { if let ty::BindByReference(..) = bm { - by_ref_span = Some(span); + by_ref_spans.push(span); } } else { cx.tcx.sess.delay_span_bug(pat.span, "missing binding mode"); } }); - let span_vec = &mut Vec::new(); + // Find bad by-move spans: + let by_move_spans = &mut Vec::new(); let mut check_move = |p: &Pat, sub: Option<&Pat>| { // Check legality of moving out of the enum. // @@ -599,11 +601,10 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo struct_span_err!(cx.tcx.sess, p.span, E0007, "cannot bind by-move with sub-bindings") .span_label(p.span, "binds an already bound by-move value by moving it") .emit(); - } else if !has_guard && by_ref_span.is_some() { - span_vec.push(p.span); + } else if !has_guard && !by_ref_spans.is_empty() { + by_move_spans.push(p.span); } }; - pat.walk(|p| { if let hir::PatKind::Binding(.., sub) = &p.kind { if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) { @@ -620,17 +621,18 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo true }); - if !span_vec.is_empty() { + // Found some bad by-move spans, error! + if !by_move_spans.is_empty() { let mut err = struct_span_err!( cx.tcx.sess, - MultiSpan::from_spans(span_vec.clone()), + MultiSpan::from_spans(by_move_spans.clone()), E0009, "cannot bind by-move and by-ref in the same pattern", ); - if let Some(by_ref_span) = by_ref_span { - err.span_label(by_ref_span, "both by-ref and by-move used"); + for span in by_ref_spans.iter() { + err.span_label(*span, "by-ref pattern here"); } - for span in span_vec.iter() { + for span in by_move_spans.iter() { err.span_label(*span, "by-move pattern here"); } err.emit(); 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 index 9157fe0b070d0..ff00aa8caa8d3 100644 --- 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 @@ -4,7 +4,7 @@ error[E0009]: cannot bind by-move and by-ref in the same pattern LL | Some((ref _y, _z)) => { }, | ------ ^^ by-move pattern here | | - | both by-ref and by-move used + | by-ref pattern here error: aborting due to previous error 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 index d53547178db11..3e8358da3507d 100644 --- 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 @@ -4,7 +4,7 @@ error[E0009]: cannot bind by-move and by-ref in the same pattern LL | DoubleOption::Some2(ref _y, _z) => { }, | ------ ^^ by-move pattern here | | - | both by-ref and by-move used + | by-ref pattern here error: aborting due to previous error 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 index 267a9dff926a2..00e0c70d6494b 100644 --- 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 @@ -2,7 +2,7 @@ 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)) => { }, - | ^^ ------ both by-ref and by-move used + | ^^ ------ by-ref pattern here | | | by-move pattern here diff --git a/src/test/ui/error-codes/E0009.stderr b/src/test/ui/error-codes/E0009.stderr index f8acb9a09d978..446a436d64779 100644 --- a/src/test/ui/error-codes/E0009.stderr +++ b/src/test/ui/error-codes/E0009.stderr @@ -2,7 +2,7 @@ error[E0009]: cannot bind by-move and by-ref in the same pattern --> $DIR/E0009.rs:5:15 | LL | Some((y, ref z)) => {}, - | ^ ----- both by-ref and by-move used + | ^ ----- by-ref pattern here | | | by-move pattern here diff --git a/src/test/ui/issues/issue-53840.stderr b/src/test/ui/issues/issue-53840.stderr index 0032f60a221f8..9cb034e7592da 100644 --- a/src/test/ui/issues/issue-53840.stderr +++ b/src/test/ui/issues/issue-53840.stderr @@ -2,7 +2,7 @@ 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) => {} - | ^ ^ ----- both by-ref and by-move used + | ^ ^ ----- by-ref pattern here | | | | | by-move pattern here | by-move pattern here @@ -11,7 +11,7 @@ error[E0009]: cannot bind by-move and by-ref in the same pattern --> $DIR/issue-53840.rs:17:14 | LL | Bar {a, ref b} => {} - | ^ ----- both by-ref and by-move used + | ^ ----- by-ref pattern here | | | by-move pattern here 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 c4afdc576a16a..63866238f565e 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 @@ -13,7 +13,7 @@ LL | Some(ref _y @ _z) => { }, | ---------^^ | | | | | by-move pattern here - | both by-ref and by-move used + | by-ref pattern here error: aborting due to previous error 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 fbf9dfff7feec..af0bcb69bbbea 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 @@ -25,7 +25,7 @@ LL | let ref a @ box b = Box::new(NC); | ------------^ | | | | | by-move pattern here - | both by-ref and by-move used + | by-ref pattern here error[E0382]: use of moved value --> $DIR/borrowck-pat-at-and-box.rs:11:18 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 9c8a4e25fb844..36dc1b2879263 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 @@ -13,7 +13,7 @@ LL | ref op_string_ref @ Some(s) => {}, | -------------------------^- | | | | | by-move pattern here - | both by-ref and by-move used + | by-ref pattern here error: aborting due to previous error 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 ce79b562ec99b..27b94e055a0a4 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 @@ -124,5 +124,5 @@ LL | drop(a); error: aborting due to 11 previous errors -Some errors have detailed explanations: E0502, E0507. +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/default-binding-modes-both-sides-independent.stderr b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr index bb0d893887e29..3cd756d11ce5e 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 @@ -13,7 +13,7 @@ LL | let ref a @ b = NotCopy; | --------^ | | | | | by-move pattern here - | both by-ref and by-move used + | by-ref pattern here error[E0009]: cannot bind by-move and by-ref in the same pattern --> $DIR/default-binding-modes-both-sides-independent.rs:22:21 @@ -22,17 +22,18 @@ LL | let ref mut a @ b = NotCopy; | ------------^ | | | | | by-move pattern here - | both by-ref and by-move used + | by-ref pattern here 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 + | --------^ --------^ + | | | | | + | | | | by-move pattern here + | | | by-ref pattern here + | | by-move pattern here + | by-ref pattern here error[E0009]: cannot bind by-move and by-ref in the same pattern --> $DIR/default-binding-modes-both-sides-independent.rs:28:17 @@ -41,7 +42,7 @@ LL | ref a @ b => {} | --------^ | | | | | by-move pattern here - | both by-ref and by-move used + | by-ref pattern here error: aborting due to 4 previous errors 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 8a1ded1d5b94a..ebc6ff5d8c3fe 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/for.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/for.stderr @@ -4,7 +4,7 @@ error[E0009]: cannot bind by-move and by-ref in the same pattern LL | for (n, mut m) in &tups { | - ^^^^^ by-move pattern here | | - | both by-ref and by-move used + | by-ref pattern here error[E0507]: cannot move out of a shared reference --> $DIR/for.rs:6:23 From eed311f719ac4cda2f1df2fae5f4ce9404cae135 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 14 Dec 2019 17:43:07 +0100 Subject: [PATCH 04/17] add check_borrow_conflicts_in_at_patterns analysis --- src/librustc_mir/hair/pattern/check_match.rs | 134 ++++++++++++++----- 1 file changed, 104 insertions(+), 30 deletions(-) diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index c3768e7438597..3f7a17183e722 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -15,6 +15,7 @@ use rustc::ty::subst::{InternalSubsts, SubstsRef}; use rustc::ty::{self, Ty, TyCtxt}; use rustc_error_codes::*; use rustc_errors::{Applicability, DiagnosticBuilder}; +use syntax::ast::Mutability; use syntax::feature_gate::feature_err; use syntax_pos::symbol::sym; use syntax_pos::{MultiSpan, Span}; @@ -122,6 +123,7 @@ 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().bindings_after_at { check_legality_of_bindings_in_at_patterns(self, pat); } @@ -639,44 +641,116 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo } } -/// Forbids bindings in `@` patterns. This is necessary for memory safety, -/// because of the way rvalues are handled in the borrow check. (See issue -/// #14587.) -fn check_legality_of_bindings_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat) { - AtBindingPatternVisitor { cx, bindings_allowed: true }.visit_pat(pat); -} +fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat) { + // Get the mutability of `p` if it's by-ref. + let extract_binding_mut = |hir_id, span| match cx.tables.pat_binding_modes().get(hir_id) { + None => { + cx.tcx.sess.delay_span_bug(span, "missing binding mode"); + None + } + Some(ty::BindByValue(..)) => None, + Some(ty::BindByReference(m)) => Some(*m), + }; + pat.walk(|pat| { + // Extract `sub` in `binding @ sub`. + let (name, sub) = match &pat.kind { + hir::PatKind::Binding(.., name, Some(sub)) => (*name, sub), + _ => return true, + }; + + // Extract the mutability. + let mut_outer = match extract_binding_mut(pat.hir_id, pat.span) { + None => return true, + Some(m) => m, + }; + + // 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::Immutable, Mutability::Immutable) => {} + (Mutability::Mutable, Mutability::Mutable) => conflicts_mut_mut.push(span), + _ => conflicts_mut_ref.push(span), + } + } + }); + + // 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 = cx.tcx.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::Mutable => ("mutable", "immutable"), + Mutability::Immutable => ("immutable", "mutable"), + }; + let msg = &format!( + "cannot borrow `{}` as {} because it is also borrowed as {}", + name, primary, also, + ); + let mut err = cx.tcx.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(); + } -struct AtBindingPatternVisitor<'a, 'b, 'tcx> { - cx: &'a MatchVisitor<'b, 'tcx>, - bindings_allowed: bool, + true + }); } -impl<'v> Visitor<'v> for AtBindingPatternVisitor<'_, '_, '_> { - fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> { - NestedVisitorMap::None +/// Forbids bindings in `@` patterns. This used to be is necessary for memory safety, +/// because of the way rvalues were handled in the borrow check. (See issue #14587.) +fn check_legality_of_bindings_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat) { + AtBindingPatternVisitor { cx, bindings_allowed: true }.visit_pat(pat); + + struct AtBindingPatternVisitor<'a, 'b, 'tcx> { + cx: &'a MatchVisitor<'b, 'tcx>, + bindings_allowed: bool, } - fn visit_pat(&mut self, pat: &Pat) { - match pat.kind { - hir::PatKind::Binding(.., ref subpat) => { - if !self.bindings_allowed { - feature_err( - &self.cx.tcx.sess.parse_sess, - sym::bindings_after_at, - pat.span, - "pattern bindings after an `@` are unstable", - ) - .emit(); - } + impl<'v> Visitor<'v> for AtBindingPatternVisitor<'_, '_, '_> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> { + NestedVisitorMap::None + } - if subpat.is_some() { - let bindings_were_allowed = self.bindings_allowed; - self.bindings_allowed = false; - intravisit::walk_pat(self, pat); - self.bindings_allowed = bindings_were_allowed; + fn visit_pat(&mut self, pat: &Pat) { + match pat.kind { + hir::PatKind::Binding(.., ref subpat) => { + if !self.bindings_allowed { + feature_err( + &self.cx.tcx.sess.parse_sess, + sym::bindings_after_at, + pat.span, + "pattern bindings after an `@` are unstable", + ) + .emit(); + } + + if subpat.is_some() { + let bindings_were_allowed = self.bindings_allowed; + self.bindings_allowed = false; + intravisit::walk_pat(self, pat); + self.bindings_allowed = bindings_were_allowed; + } } + _ => intravisit::walk_pat(self, pat), } - _ => intravisit::walk_pat(self, pat), } } } From 5a8baa28763a706ff7a338b1492ca31cf8c615c1 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 14 Dec 2019 23:18:39 +0100 Subject: [PATCH 05/17] refactor with extract_binding_mode --- src/librustc/ty/context.rs | 7 +++ src/librustc_mir/build/mod.rs | 11 ++-- src/librustc_mir/hair/pattern/check_match.rs | 61 ++++++++------------ src/librustc_typeck/check/regionck.rs | 19 ++---- src/librustc_typeck/check/writeback.rs | 5 +- src/librustc_typeck/expr_use_visitor.rs | 4 +- 6 files changed, 45 insertions(+), 62 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 0806e2d77650e..e36b11ae0050c 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -648,6 +648,13 @@ impl<'tcx> TypeckTables<'tcx> { } } + pub fn extract_binding_mode(&self, s: &Session, id: HirId, sp: Span) -> Option { + self.pat_binding_modes().get(id).copied().or_else(|| { + s.delay_span_bug(sp, "missing binding mode"); + None + }) + } + pub fn pat_binding_modes(&self) -> LocalTableInContext<'_, BindingMode> { LocalTableInContext { local_id_root: self.local_id_root, diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 3b85a5d3c911b..3a2a2dc412e72 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -816,15 +816,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if let Some(Node::Binding(pat)) = tcx_hir.find(var_id) { if let hir::PatKind::Binding(_, _, ident, _) = pat.kind { name = ident.name; - - if let Some(&bm) = hir_tables.pat_binding_modes().get(pat.hir_id) { - if bm == ty::BindByValue(hir::Mutability::Mut) { + match hir_tables.extract_binding_mode(tcx.sess, pat.hir_id, pat.span) { + Some(ty::BindByValue(hir::Mutability::Mut)) => { mutability = Mutability::Mut; - } else { - mutability = Mutability::Not; } - } else { - tcx.sess.delay_span_bug(pat.span, "missing binding mode"); + Some(_) => mutability = Mutability::Not, + _ => {} } } } diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 3f7a17183e722..3cfafaf180634 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -271,11 +271,9 @@ fn const_not_var(err: &mut DiagnosticBuilder<'_>, tcx: TyCtxt<'_>, pat: &Pat, pa fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pat) { pat.walk(|p| { if let hir::PatKind::Binding(_, _, ident, None) = p.kind { - if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) { - if bm != ty::BindByValue(hir::Mutability::Not) { - // Nothing to check. - return true; - } + if let Some(ty::BindByValue(hir::Mutability::Not)) = + cx.tables.extract_binding_mode(cx.tcx.sess, p.hir_id, p.span) + { let pat_ty = cx.tables.pat_ty(p); if let ty::Adt(edef, _) = pat_ty.kind { if edef.is_enum() @@ -303,8 +301,6 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pa err.emit(); } } - } else { - cx.tcx.sess.delay_span_bug(p.span, "missing binding mode"); } } true @@ -581,15 +577,14 @@ fn maybe_point_at_variant(ty: Ty<'_>, patterns: &[super::Pat<'_>]) -> Vec // 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; + let tables = cx.tables; + // Find all by-ref spans. let mut by_ref_spans = Vec::new(); pat.each_binding(|_, hir_id, span, _| { - if let Some(&bm) = cx.tables.pat_binding_modes().get(hir_id) { - if let ty::BindByReference(..) = bm { - by_ref_spans.push(span); - } - } else { - cx.tcx.sess.delay_span_bug(pat.span, "missing binding mode"); + if let Some(ty::BindByReference(_)) = tables.extract_binding_mode(sess, hir_id, span) { + by_ref_spans.push(span); } }); @@ -600,7 +595,7 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo // // `x @ Foo(..)` is legal, but `x @ Foo(y)` isn't. if sub.map_or(false, |p| p.contains_bindings()) { - struct_span_err!(cx.tcx.sess, p.span, E0007, "cannot bind by-move with sub-bindings") + struct_span_err!(sess, p.span, E0007, "cannot bind by-move with sub-bindings") .span_label(p.span, "binds an already bound by-move value by moving it") .emit(); } else if !has_guard && !by_ref_spans.is_empty() { @@ -609,15 +604,11 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo }; pat.walk(|p| { if let hir::PatKind::Binding(.., sub) = &p.kind { - if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) { - if let ty::BindByValue(..) = bm { - let pat_ty = cx.tables.node_type(p.hir_id); - if !pat_ty.is_copy_modulo_regions(cx.tcx, cx.param_env, pat.span) { - check_move(p, sub.as_deref()); - } + 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) { + check_move(p, sub.as_deref()); } - } else { - cx.tcx.sess.delay_span_bug(pat.span, "missing binding mode"); } } true @@ -626,7 +617,7 @@ 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!( - cx.tcx.sess, + sess, MultiSpan::from_spans(by_move_spans.clone()), E0009, "cannot bind by-move and by-ref in the same pattern", @@ -642,14 +633,12 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo } 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 cx.tables.pat_binding_modes().get(hir_id) { - None => { - cx.tcx.sess.delay_span_bug(span, "missing binding mode"); - None - } - Some(ty::BindByValue(..)) => None, - Some(ty::BindByReference(m)) => Some(*m), + let extract_binding_mut = |hir_id, span| match tab.extract_binding_mode(sess, hir_id, span)? { + ty::BindByValue(_) => None, + ty::BindByReference(m) => Some(m), }; pat.walk(|pat| { // Extract `sub` in `binding @ sub`. @@ -671,8 +660,8 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat) { sub.each_binding(|_, hir_id, span, _| { if let Some(mut_inner) = extract_binding_mut(hir_id, span) { match (mut_outer, mut_inner) { - (Mutability::Immutable, Mutability::Immutable) => {} - (Mutability::Mutable, Mutability::Mutable) => conflicts_mut_mut.push(span), + (Mutability::Not, Mutability::Not) => {} + (Mutability::Mut, Mutability::Mut) => conflicts_mut_mut.push(span), _ => conflicts_mut_ref.push(span), } } @@ -683,7 +672,7 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat) { 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 = cx.tcx.sess.struct_span_err(pat.span, msg); + 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"); @@ -695,14 +684,14 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat) { } 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::Mutable => ("mutable", "immutable"), - Mutability::Immutable => ("immutable", "mutable"), + Mutability::Mut => ("mutable", "immutable"), + Mutability::Not => ("immutable", "mutable"), }; let msg = &format!( "cannot borrow `{}` as {} because it is also borrowed as {}", name, primary, also, ); - let mut err = cx.tcx.sess.struct_span_err(pat.span, msg); + 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)); diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 8abfc2981a6a4..149f27ed305fb 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -1007,20 +1007,13 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { fn link_pattern(&self, discr_cmt: mc::Place<'tcx>, root_pat: &hir::Pat) { debug!("link_pattern(discr_cmt={:?}, root_pat={:?})", discr_cmt, root_pat); ignore_err!(self.with_mc(|mc| { - mc.cat_pattern(discr_cmt, root_pat, |sub_cmt, sub_pat| { + mc.cat_pattern(discr_cmt, root_pat, |sub_cmt, hir::Pat { kind, span, hir_id }| { // `ref x` pattern - if let PatKind::Binding(..) = sub_pat.kind { - if let Some(&bm) = mc.tables.pat_binding_modes().get(sub_pat.hir_id) { - if let ty::BindByReference(mutbl) = bm { - self.link_region_from_node_type( - sub_pat.span, - sub_pat.hir_id, - mutbl, - &sub_cmt, - ); - } - } else { - self.tcx.sess.delay_span_bug(sub_pat.span, "missing binding mode"); + if let PatKind::Binding(..) = kind { + if let Some(ty::BindByReference(mutbl)) = + mc.tables.extract_binding_mode(self.tcx.sess, *hir_id, *span) + { + self.link_region_from_node_type(*span, *hir_id, mutbl, &sub_cmt); } } }) diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 8ed8751f65c9a..5ef5f4c648e8c 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -284,10 +284,9 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> { fn visit_pat(&mut self, p: &'tcx hir::Pat) { match p.kind { hir::PatKind::Binding(..) => { - if let Some(&bm) = self.fcx.tables.borrow().pat_binding_modes().get(p.hir_id) { + let tables = self.fcx.tables.borrow(); + if let Some(bm) = tables.extract_binding_mode(self.tcx().sess, p.hir_id, p.span) { self.tables.pat_binding_modes_mut().insert(p.hir_id, bm); - } else { - self.tcx().sess.delay_span_bug(p.span, "missing binding mode"); } } hir::PatKind::Struct(_, ref fields, _) => { diff --git a/src/librustc_typeck/expr_use_visitor.rs b/src/librustc_typeck/expr_use_visitor.rs index 58baf24438bd0..788dda1cd5a0e 100644 --- a/src/librustc_typeck/expr_use_visitor.rs +++ b/src/librustc_typeck/expr_use_visitor.rs @@ -534,7 +534,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { return_if_err!(mc.cat_pattern(discr_place.clone(), pat, |place, pat| { if let PatKind::Binding(_, canonical_id, ..) = pat.kind { debug!("walk_pat: binding place={:?} pat={:?}", place, pat,); - if let Some(&bm) = mc.tables.pat_binding_modes().get(pat.hir_id) { + if let Some(bm) = mc.tables.extract_binding_mode(tcx.sess, pat.hir_id, pat.span) { debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm); // pat_ty: the type of the binding being produced. @@ -560,8 +560,6 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { delegate.consume(place, mode); } } - } else { - tcx.sess.delay_span_bug(pat.span, "missing binding mode"); } } })); From b9aba749cfc192422d879b12c7a5c3674f5ad110 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 14 Dec 2019 23:43:21 +0100 Subject: [PATCH 06/17] improve robustness of pat walkers --- src/librustc/hir/mod.rs | 10 ++++++++++ src/librustc/hir/pat_util.rs | 3 +-- src/librustc_mir/hair/pattern/check_match.rs | 14 +++++--------- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 4aa8c12a219ca..a85685caf7d7a 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -921,6 +921,16 @@ impl Pat { pub fn walk(&self, mut it: impl FnMut(&Pat) -> bool) { self.walk_(&mut it) } + + /// Walk the pattern in left-to-right order. + /// + /// If you always want to recurse, prefer this method over `walk`. + pub fn walk_always(&self, mut it: impl FnMut(&Pat)) { + self.walk(|p| { + it(p); + true + }) + } } /// A single field in a struct pattern. diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs index c0aa54beac275..8d3b464a8ffa1 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -79,11 +79,10 @@ impl hir::Pat { /// Call `f` on every "binding" in a pattern, e.g., on `a` in /// `match foo() { Some(a) => (), None => () }` pub fn each_binding(&self, mut f: impl FnMut(hir::BindingAnnotation, HirId, Span, ast::Ident)) { - self.walk(|p| { + self.walk_always(|p| { if let PatKind::Binding(binding_mode, _, ident, _) = p.kind { f(binding_mode, p.hir_id, p.span, ident); } - true }); } diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 3cfafaf180634..30501e4504dcc 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -269,7 +269,7 @@ fn const_not_var(err: &mut DiagnosticBuilder<'_>, tcx: TyCtxt<'_>, pat: &Pat, pa } fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pat) { - pat.walk(|p| { + pat.walk_always(|p| { if let hir::PatKind::Binding(_, _, ident, None) = p.kind { if let Some(ty::BindByValue(hir::Mutability::Not)) = cx.tables.extract_binding_mode(cx.tcx.sess, p.hir_id, p.span) @@ -303,7 +303,6 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pa } } } - true }); } @@ -602,7 +601,7 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo by_move_spans.push(p.span); } }; - pat.walk(|p| { + 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); @@ -611,7 +610,6 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo } } } - true }); // Found some bad by-move spans, error! @@ -640,16 +638,16 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat) { ty::BindByValue(_) => None, ty::BindByReference(m) => Some(m), }; - pat.walk(|pat| { + pat.walk_always(|pat| { // Extract `sub` in `binding @ sub`. let (name, sub) = match &pat.kind { hir::PatKind::Binding(.., name, Some(sub)) => (*name, sub), - _ => return true, + _ => return, }; // Extract the mutability. let mut_outer = match extract_binding_mut(pat.hir_id, pat.span) { - None => return true, + None => return, Some(m) => m, }; @@ -698,8 +696,6 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat) { } err.emit(); } - - true }); } From 10ac7ea127bbef189f71befafbb7faf3489a9d41 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 14 Dec 2019 23:57:20 +0100 Subject: [PATCH 07/17] document check_borrow_conflicts_in_at_patterns --- src/librustc_mir/hair/pattern/check_match.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 30501e4504dcc..8abe3508fd681 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -317,7 +317,7 @@ fn pat_is_catchall(pat: &Pat) -> bool { } } -// Check for unreachable patterns +/// Check for unreachable patterns. fn check_arms<'p, 'tcx>( cx: &mut MatchCheckCtxt<'p, 'tcx>, arms: &[(&'p super::Pat<'tcx>, &hir::Pat, bool)], @@ -574,7 +574,7 @@ fn maybe_point_at_variant(ty: Ty<'_>, patterns: &[super::Pat<'_>]) -> Vec covered } -// Check the legality of legality of by-move bindings. +/// Check the legality of legality of by-move bindings. fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: bool, pat: &Pat) { let sess = cx.tcx.sess; let tables = cx.tables; @@ -630,6 +630,14 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo } } +/// Check that there are no borrow 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)`. +/// +/// 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; From 9ab36037a45814b642d7e9641d2f95788ce37d6b Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Dec 2019 00:32:20 +0100 Subject: [PATCH 08/17] --bless bindings-after-at tests --- src/librustc_mir/hair/pattern/check_match.rs | 2 +- .../borrowck-pat-at-and-box.rs | 12 +- .../borrowck-pat-at-and-box.stderr | 44 +++- .../borrowck-pat-ref-mut-and-ref.rs | 59 +++-- .../borrowck-pat-ref-mut-and-ref.stderr | 237 +++++++++++++++++- .../borrowck-pat-ref-mut-twice.rs | 40 ++- .../borrowck-pat-ref-mut-twice.stderr | 171 +++++++++++-- 7 files changed, 498 insertions(+), 67 deletions(-) diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 8abe3508fd681..67c89c7293c43 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -695,7 +695,7 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat) { }; let msg = &format!( "cannot borrow `{}` as {} because it is also borrowed as {}", - name, primary, also, + name, also, primary, ); let mut err = sess.struct_span_err(pat.span, msg); err.span_label(binding_span, &format!("{} borrow occurs here", primary)); 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 4d94d94ae0e18..7a4fe96b21330 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 @@ -29,16 +29,20 @@ fn main() { 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. + let ref a @ box ref mut b = Box::new(NC); + //~^ ERROR cannot borrow `a` 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 *b = NC; let ref a @ box ref mut b = Box::new(NC); - //~^ ERROR cannot borrow `_` 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 `_` 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 + //~^ ERROR cannot borrow `a` 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 af0bcb69bbbea..7bb2379968e5d 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 @@ -27,6 +27,42 @@ LL | let ref a @ box b = Box::new(NC); | | by-move pattern here | by-ref pattern here +error: cannot borrow `a` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-at-and-box.rs:32:9 + | +LL | let ref a @ box ref mut b = Box::new(NC); + | -----^^^^^^^--------- + | | | + | | mutable borrow occurs here + | immutable borrow occurs here + +error: cannot borrow `a` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-at-and-box.rs:34:9 + | +LL | let ref a @ box ref mut b = Box::new(NC); + | -----^^^^^^^--------- + | | | + | | mutable borrow occurs here + | immutable borrow occurs here + +error: cannot borrow `a` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-at-and-box.rs:37:9 + | +LL | let ref a @ box ref mut b = Box::new(NC); + | -----^^^^^^^--------- + | | | + | | mutable borrow occurs here + | immutable borrow occurs here + +error: cannot borrow `a` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-at-and-box.rs:43:9 + | +LL | let ref mut a @ box ref b = Box::new(NC); + | ---------^^^^^^^----- + | | | + | | immutable borrow occurs here + | mutable borrow occurs here + error[E0382]: use of moved value --> $DIR/borrowck-pat-at-and-box.rs:11:18 | @@ -46,7 +82,7 @@ LL | let a @ box b = Box::new(C); | 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 + --> $DIR/borrowck-pat-at-and-box.rs:37:21 | LL | let ref a @ box ref mut b = Box::new(NC); | ------------^^^^^^^^^ @@ -58,18 +94,18 @@ 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 + --> $DIR/borrowck-pat-at-and-box.rs:43: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 +error: aborting due to 11 previous errors Some errors have detailed explanations: E0007, E0009, E0382, E0502. For more information about an error, try `rustc --explain E0007`. 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 3ea3d93f862f5..35dddfdbb1fbb 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,8 @@ enum Option { 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 + //~^ ERROR cannot borrow `z` 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); } @@ -18,30 +19,38 @@ fn main() { 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. + let ref a @ ref mut b = U; + //~^ ERROR cannot borrow `a` 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 + let ref a @ (ref mut b, ref mut c) = (U, U); + //~^ ERROR cannot borrow `a` 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 - // 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. + //~^ ERROR cannot borrow `a` 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 *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. + //~^ 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 + *a = Err(U); 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 `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 `_` 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); @@ -50,38 +59,50 @@ fn main() { 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 + //~^ 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 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 + //~^ 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 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 + //~^ 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 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 + //~^ 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 move out of `a` in pattern guard _ => {} } let ref a @ (ref mut b, ref mut c) = (U, U); - *b = U; // FIXME: ^ should not compile. + //~^ ERROR cannot borrow `a` 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 `_` 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 `_` 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 + //~^ ERROR cannot borrow `a` 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); // FIXME: This should not compile. + let ref mut a @ (ref b, ref c) = (U, U); + //~^ ERROR cannot borrow `a` 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 27b94e055a0a4..7059f3c7caa8c 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 @@ -6,6 +6,219 @@ LL | #![feature(bindings_after_at)] | = note: `#[warn(incomplete_features)]` on by default +error: cannot borrow `z` 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 + +error: cannot borrow `a` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:22:9 + | +LL | let ref a @ ref mut b = U; + | -----^^^--------- + | | | + | | mutable borrow occurs here + | 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:24:9 + | +LL | let ref mut a @ ref b = U; + | ---------^^^----- + | | | + | | immutable borrow occurs here + | 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:26: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 + +error: cannot borrow `a` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:9 + | +LL | let ref mut a @ (ref b, ref c) = (U, U); + | ---------^^^^-----^^-----^ + | | | | + | | | immutable borrow occurs here + | | immutable borrow occurs here + | 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:31:9 + | +LL | let ref mut a @ ref b = U; + | ---------^^^----- + | | | + | | immutable borrow occurs here + | 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:35:9 + | +LL | let ref a @ ref mut b = U; + | -----^^^--------- + | | | + | | mutable borrow occurs here + | 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 + | +LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { + | ---------^^^^^^-----^ + | | | + | | immutable borrow occurs here + | 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:41:33 + | +LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { + | ---------^^^^^^^-----^ + | | | + | | immutable borrow occurs here + | 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:50:9 + | +LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { + | -----^^^^^^---------^ + | | | + | | 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:50:33 + | +LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { + | -----^^^^^^^---------^ + | | | + | | 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:61: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 + +error: cannot borrow `a` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:61: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 + +error: cannot borrow `a` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:68: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 + +error: cannot borrow `a` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:68: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 + +error: cannot borrow `a` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75: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 + +error: cannot borrow `a` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75: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 + +error: cannot borrow `a` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:82: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 + +error: cannot borrow `a` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:82: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 + +error: cannot borrow `a` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:89: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 + +error: cannot borrow `a` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:94: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 + +error: cannot borrow `a` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:101: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 + +error: cannot borrow `a` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:106:9 + | +LL | let ref mut a @ (ref b, ref c) = (U, U); + | ---------^^^^-----^^-----^ + | | | | + | | | immutable borrow occurs here + | | immutable borrow occurs here + | mutable borrow occurs here + error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:31 | @@ -14,12 +227,12 @@ 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 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:50:20 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----------^^^^^^^^^- @@ -31,7 +244,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:43:45 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:50:45 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | ------------^^^^^^^^^- @@ -43,7 +256,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:52:61 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:61:61 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | ^^^^^^ cannot assign @@ -51,7 +264,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:57:61 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:68:61 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ^^^^^^^^^^^ cannot assign @@ -59,7 +272,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:62:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75: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 @@ -67,7 +280,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:67:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:82: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 @@ -75,7 +288,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:76:18 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:94:18 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | ---------^^^^^^^^^------------ @@ -87,7 +300,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:76:29 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:94:29 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | --------------------^^^^^^^^^- @@ -99,7 +312,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:82:18 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:101:18 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | ---------^^^^^^^^^------------ @@ -111,7 +324,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:82:29 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:101:29 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | --------------------^^^^^^^^^- @@ -122,7 +335,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 11 previous errors +error: aborting due to 34 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 482fa0497f571..f76d9ce73cf25 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 @@ -7,20 +7,32 @@ fn main() { struct U; let ref mut a @ ref mut b = U; - //~^ ERROR cannot borrow `_` as mutable more than once at a time + //~^ ERROR cannot borrow `a` 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; // FIXME: This should not compile. + let ref mut a @ ref mut b = U; + //~^ ERROR cannot borrow `a` as mutable more than once at a time 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 `a` as mutable more than once at a time let ref mut a @ ref mut b = U; - //~^ ERROR cannot borrow `_` as mutable more than once at a time + //~^ ERROR cannot borrow `a` 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; // FIXME: This should not compile. + let ref mut a @ ref mut b = U; + //~^ ERROR cannot borrow `a` as mutable more than once at a time *b = U; - let ref mut a @ (ref mut b, [ref mut c, ref mut d]) = (U, [U, U]); - // FIXME: This should not compile. + let ref mut a @ ( + //~^ ERROR cannot borrow `a` as mutable more than once at a time + ref mut b, + [ + ref mut c, + ref mut d, + ref e, + ] + ) = (U, [U, U, U]); let a @ (ref mut b, ref mut c) = (U, U); //~^ ERROR cannot bind by-move with sub-bindings @@ -39,18 +51,22 @@ fn main() { match Ok(U) { ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { - // FIXME: This should not compile. + //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~| ERROR cannot borrow `a` 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 *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 `a` as mutable more than once at a time + //~| ERROR cannot borrow `a` 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); @@ -60,7 +76,9 @@ fn main() { } 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 `a` as mutable more than once at a time + //~| ERROR cannot borrow `a` 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 c9bfba867787e..e8176342a0c45 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 @@ -6,30 +6,169 @@ LL | #![feature(bindings_after_at)] | = note: `#[warn(incomplete_features)]` on by default +error: cannot borrow `a` as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:9:9 + | +LL | let ref mut a @ ref mut b = U; + | ---------^^^--------- + | | | + | | another mutable borrow occurs here + | first mutable borrow occurs here + +error: cannot borrow `a` as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:13:9 + | +LL | let ref mut a @ ref mut b = U; + | ---------^^^--------- + | | | + | | another mutable borrow occurs here + | first mutable borrow occurs here + +error: cannot borrow `a` as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:16:9 + | +LL | let ref mut a @ ref mut b = U; + | ---------^^^--------- + | | | + | | another mutable borrow occurs here + | first mutable borrow occurs here + +error: cannot borrow `a` as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:19:9 + | +LL | let ref mut a @ ref mut b = U; + | ---------^^^--------- + | | | + | | another mutable borrow occurs here + | first mutable borrow occurs here + +error: cannot borrow `a` as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:23:9 + | +LL | let ref mut a @ ref mut b = U; + | ---------^^^--------- + | | | + | | another mutable borrow occurs here + | first mutable borrow occurs here + +error: cannot borrow `a` as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:27:9 + | +LL | let ref mut a @ ( + | ^-------- + | | + | _________first mutable borrow occurs here + | | +LL | | +LL | | ref mut b, + | | --------- another mutable borrow occurs here +LL | | [ +LL | | ref mut c, + | | --------- another mutable borrow occurs here +LL | | ref mut d, + | | --------- another mutable borrow occurs here +LL | | ref e, + | | ----- also borrowed as immutable here +LL | | ] +LL | | ) = (U, [U, U, U]); + | |_____^ + error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:25:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:37: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 + --> $DIR/borrowck-pat-ref-mut-twice.rs:41: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 + --> $DIR/borrowck-pat-ref-mut-twice.rs:45: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 + --> $DIR/borrowck-pat-ref-mut-twice.rs:48: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: cannot borrow `a` as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:53: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 + +error: cannot borrow `a` as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:53: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 + +error: cannot borrow `a` as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:59: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 + +error: cannot borrow `a` as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:59: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 + +error: cannot borrow `a` as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:66: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 + +error: cannot borrow `a` as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:66: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 + +error: cannot borrow `a` as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:78: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 + +error: cannot borrow `a` as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:78: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 + error[E0499]: cannot borrow `_` as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:9:21 | @@ -38,24 +177,24 @@ 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 + --> $DIR/borrowck-pat-ref-mut-twice.rs:19: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 + --> $DIR/borrowck-pat-ref-mut-twice.rs:37: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 @@ -64,7 +203,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:29:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:41: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 @@ -73,7 +212,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:33:18 + --> $DIR/borrowck-pat-ref-mut-twice.rs:45: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 @@ -82,7 +221,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:36:30 + --> $DIR/borrowck-pat-ref-mut-twice.rs:48: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 @@ -91,7 +230,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:52:24 + --> $DIR/borrowck-pat-ref-mut-twice.rs:66:24 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------------^^^^^^^^^- @@ -103,7 +242,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:52:53 + --> $DIR/borrowck-pat-ref-mut-twice.rs:66:53 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ----------------^^^^^^^^^- @@ -115,7 +254,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:62:24 + --> $DIR/borrowck-pat-ref-mut-twice.rs:78:24 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------------^^^^^^^^^- @@ -127,7 +266,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:62:53 + --> $DIR/borrowck-pat-ref-mut-twice.rs:78:53 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ----------------^^^^^^^^^- @@ -138,7 +277,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 14 previous errors +error: aborting due to 28 previous errors Some errors have detailed explanations: E0007, E0382, E0499. For more information about an error, try `rustc --explain E0007`. From 0034e6199e1ff234715aea73cdd31c9f149f334e Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Dec 2019 00:50:44 +0100 Subject: [PATCH 09/17] bindings_after_at: harden tests wrt. promotion --- .../borrowck-move-and-move.rs | 7 ++ .../borrowck-move-and-move.stderr | 33 ++++-- .../borrowck-pat-at-and-box.rs | 11 ++ .../borrowck-pat-at-and-box.stderr | 33 ++++-- .../borrowck-pat-by-copy-bindings-in-at.rs | 12 +- .../borrowck-pat-by-move-and-ref.rs | 2 +- .../borrowck-pat-ref-both-sides.rs | 16 ++- .../borrowck-pat-ref-mut-and-ref.rs | 14 +++ .../borrowck-pat-ref-mut-and-ref.stderr | 108 ++++++++++++------ .../borrowck-pat-ref-mut-twice.rs | 12 ++ .../borrowck-pat-ref-mut-twice.stderr | 80 ++++++++----- 11 files changed, 235 insertions(+), 93 deletions(-) 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 e18d3bc06a933..ba1c8e132f25d 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 @@ -6,6 +6,9 @@ fn main() { struct U; // Not copy! + // Prevent promotion: + fn u() -> U { U } + let a @ b = U; //~^ ERROR cannot bind by-move with sub-bindings //~| ERROR use of moved value @@ -14,6 +17,10 @@ fn main() { //~^ 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 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 0b69ff0b8392c..f08692264e231 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 @@ -7,31 +7,37 @@ 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 + --> $DIR/borrowck-move-and-move.rs:12: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 + --> $DIR/borrowck-move-and-move.rs:16: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 + --> $DIR/borrowck-move-and-move.rs:20: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:25: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 + --> $DIR/borrowck-move-and-move.rs:25: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 + --> $DIR/borrowck-move-and-move.rs:12:13 | LL | let a @ b = U; | ----^ - move occurs because value has type `main::U`, which does not implement the `Copy` trait @@ -40,7 +46,7 @@ LL | let a @ b = U; | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:13: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 @@ -49,7 +55,16 @@ LL | let a @ (b, c) = (U, U); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:18:16 + --> $DIR/borrowck-move-and-move.rs:20: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:25:16 | LL | match Ok(U) { | ----- move occurs because value has type `std::result::Result`, which does not implement the `Copy` trait @@ -60,7 +75,7 @@ LL | a @ Ok(b) | a @ Err(b) => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:18:29 + --> $DIR/borrowck-move-and-move.rs:25:29 | LL | match Ok(U) { | ----- move occurs because value has type `std::result::Result`, which does not implement the `Copy` trait @@ -70,7 +85,7 @@ LL | a @ Ok(b) | a @ Err(b) => {} | | value used here after move | value moved here -error: aborting due to 8 previous errors +error: aborting due to 10 previous errors Some errors have detailed explanations: E0007, E0382. For more information about an error, try `rustc --explain E0007`. 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 7a4fe96b21330..cf765f579e002 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 @@ -7,6 +7,8 @@ #[derive(Copy, Clone)] struct C; +fn c() -> C { C } + fn main() { let a @ box &b = Box::new(&C); //~^ ERROR cannot bind by-move with sub-bindings @@ -21,14 +23,23 @@ fn main() { drop(b); drop(a); + let ref a @ box b = Box::new(c()); // OK; the type is `Copy`. + drop(b); + drop(b); + drop(a); + struct NC; + fn nc() -> NC { 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()); + //~^ ERROR cannot borrow `a` 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 let ref a @ box ref mut b = Box::new(NC); 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 7bb2379968e5d..19cd0b7c1d39a 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 @@ -7,19 +7,19 @@ 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 + --> $DIR/borrowck-pat-at-and-box.rs:13: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 + --> $DIR/borrowck-pat-at-and-box.rs:17: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 + --> $DIR/borrowck-pat-at-and-box.rs:35:21 | LL | let ref a @ box b = Box::new(NC); | ------------^ @@ -28,7 +28,16 @@ LL | let ref a @ box b = Box::new(NC); | by-ref pattern here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:32:9 + --> $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 + +error: cannot borrow `a` 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); | -----^^^^^^^--------- @@ -37,7 +46,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:34:9 + --> $DIR/borrowck-pat-at-and-box.rs:45:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- @@ -46,7 +55,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:37:9 + --> $DIR/borrowck-pat-at-and-box.rs:48:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- @@ -55,7 +64,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:43:9 + --> $DIR/borrowck-pat-at-and-box.rs:54:9 | LL | let ref mut a @ box ref b = Box::new(NC); | ---------^^^^^^^----- @@ -64,7 +73,7 @@ LL | let ref mut a @ box ref b = Box::new(NC); | mutable borrow occurs here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:11:18 + --> $DIR/borrowck-pat-at-and-box.rs:13: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 @@ -73,7 +82,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:15:17 + --> $DIR/borrowck-pat-at-and-box.rs:17: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 @@ -82,7 +91,7 @@ LL | let a @ box b = Box::new(C); | value moved here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:37:21 + --> $DIR/borrowck-pat-at-and-box.rs:48:21 | LL | let ref a @ box ref mut b = Box::new(NC); | ------------^^^^^^^^^ @@ -94,7 +103,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:43:25 + --> $DIR/borrowck-pat-at-and-box.rs:54:25 | LL | let ref mut a @ box ref b = Box::new(NC); | ----------------^^^^^ @@ -105,7 +114,7 @@ LL | let ref mut a @ box ref b = Box::new(NC); LL | *a = Box::new(NC); | -- mutable borrow later used here -error: aborting due to 11 previous errors +error: aborting due to 12 previous errors Some errors have detailed explanations: E0007, E0009, E0382, E0502. For more information about an error, try `rustc --explain E0007`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs index 1115dd5b5a289..4cdbfd636f352 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs @@ -9,6 +9,8 @@ #[derive(Copy, Clone)] struct C; +fn mk_c() -> C { C } + #[derive(Copy, Clone)] struct P(A, B); @@ -16,12 +18,12 @@ enum E { 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, mk_c()); + let a @ P(b, P(c, d)) = P(mk_c(), P(C, C)); let a @ [b, c] = [C, C]; - let a @ [b, .., c] = [C, C, C]; + let a @ [b, .., c] = [C, mk_c(), C]; let a @ &(b, c) = &(C, C); - let a @ &(b, &P(c, d)) = &(C, &P(C, C)); + let a @ &(b, &P(c, d)) = &(mk_c(), &P(C, C)); use self::E::*; match L(C) { @@ -31,7 +33,7 @@ fn main() { drop(a); } } - match R(&L(&C)) { + match R(&L(&mk_c())) { L(L(&a)) | L(R(&a)) | R(L(&a)) | R(R(&a)) => { let a: C = a; drop(a); 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 4b7f61c365e34..5852e30722909 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 @@ -4,7 +4,7 @@ fn main() { match Some("hi".to_string()) { ref op_string_ref @ Some(s) => {}, - //~^ ERROR E0009 + //~^ ERROR cannot bind by-move and by-ref in the same pattern [E0009] None => {}, } } diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs index 5fbedd02d25e5..3c501ad8f8a50 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs @@ -9,27 +9,35 @@ fn main() { struct U; // Not copy! + // Promotion: let ref a @ ref b = U; let _: &U = a; let _: &U = b; - let ref a @ (ref b, [ref c, ref d]) = (U, [U, U]); + // Prevent promotion: + fn u() -> U { U } + + 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 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 ref a @ &ref b = &u(); let _: &&U = a; let _: &U = b; - match Ok(U) { + match Ok(u()) { ref a @ Ok(ref b) | ref a @ Err(ref b) => { let _: &Result = a; let _: &U = b; 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 35dddfdbb1fbb..54b4e1cae85c9 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 @@ -19,6 +19,9 @@ fn main() { struct U; + // Prevent promotion: + fn u() -> U { U } + let ref a @ ref mut b = U; //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable let ref mut a @ ref b = U; @@ -28,6 +31,17 @@ fn main() { let ref mut a @ (ref b, ref c) = (U, U); //~^ ERROR cannot borrow `a` 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 `_` 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 `_` 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 *a = U; 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 7059f3c7caa8c..04944c1d528d0 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 @@ -16,7 +16,7 @@ LL | ref mut z @ &mut Some(ref a) => { | 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:22:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:25:9 | LL | let ref a @ ref mut b = U; | -----^^^--------- @@ -25,7 +25,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:24:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:27:9 | LL | let ref mut a @ ref b = U; | ---------^^^----- @@ -34,7 +34,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:26:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:29:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -44,7 +44,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:28:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ @@ -54,7 +54,25 @@ 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:31:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:34:9 + | +LL | let ref mut a @ ref b = u(); + | ---------^^^----- + | | | + | | immutable borrow occurs here + | 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 + | +LL | let ref a @ ref mut b = u(); + | -----^^^--------- + | | | + | | mutable borrow occurs here + | 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:45:9 | LL | let ref mut a @ ref b = U; | ---------^^^----- @@ -63,7 +81,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:35:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:49:9 | LL | let ref a @ ref mut b = U; | -----^^^--------- @@ -72,7 +90,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:41:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:55:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | ---------^^^^^^-----^ @@ -81,7 +99,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:41:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:55:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | ---------^^^^^^^-----^ @@ -90,7 +108,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:50:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:64:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----^^^^^^---------^ @@ -99,7 +117,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:50:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:64:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----^^^^^^^---------^ @@ -108,7 +126,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:61:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | -----^^^^^^---------^ @@ -117,7 +135,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:61:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | -----^^^^^^^---------^ @@ -126,7 +144,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:68:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:82:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ---------^^^^^^-----^ @@ -135,7 +153,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:68:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:82:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ---------^^^^^^^-----^ @@ -144,7 +162,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:75: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 { drop(b); false } => {} | -----^^^^^^---------^ @@ -153,7 +171,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:75: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 { drop(b); false } => {} | -----^^^^^^^---------^ @@ -162,7 +180,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:82: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 { drop(a); false } => {} | ---------^^^^^^-----^ @@ -171,7 +189,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:82: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 { drop(a); false } => {} | ---------^^^^^^^-----^ @@ -180,7 +198,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:89:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -190,7 +208,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:94:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -200,7 +218,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:101:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:115:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -210,7 +228,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:106:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ @@ -231,8 +249,32 @@ LL | ref mut z @ &mut Some(ref a) => { 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:34:21 + | +LL | let ref mut a @ ref b = u(); + | ------------^^^^^ + | | | + | | immutable borrow occurs here + | mutable borrow occurs here +... +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:39:17 + | +LL | let ref a @ ref mut b = 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:50:20 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:64:20 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----------^^^^^^^^^- @@ -244,7 +286,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:50:45 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:64:45 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | ------------^^^^^^^^^- @@ -256,7 +298,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:61:61 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75:61 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | ^^^^^^ cannot assign @@ -264,7 +306,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:68:61 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:82:61 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ^^^^^^^^^^^ cannot assign @@ -272,7 +314,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:75:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:89: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 @@ -280,7 +322,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:82:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96: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 @@ -288,7 +330,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:94:18 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:18 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | ---------^^^^^^^^^------------ @@ -300,7 +342,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:94:29 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:29 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | --------------------^^^^^^^^^- @@ -312,7 +354,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:101:18 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:115:18 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | ---------^^^^^^^^^------------ @@ -324,7 +366,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:101:29 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:115:29 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | --------------------^^^^^^^^^- @@ -335,7 +377,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 34 previous errors +error: aborting due to 38 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 f76d9ce73cf25..487ac4b852b6e 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 @@ -6,6 +6,8 @@ fn main() { struct U; + fn u() -> U { U } + let ref mut a @ ref mut b = U; //~^ ERROR cannot borrow `a` as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time @@ -34,6 +36,16 @@ fn main() { ] ) = (U, [U, U, U]); + let ref mut a @ ( + //~^ ERROR cannot borrow `a` as mutable more than once at a time + ref mut b, + [ + ref mut c, + ref mut d, + ref e, + ] + ) = (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 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 e8176342a0c45..011e18be8b294 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 @@ -7,7 +7,7 @@ LL | #![feature(bindings_after_at)] = note: `#[warn(incomplete_features)]` on by default error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:9:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:11:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -16,7 +16,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:13:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:15:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -25,7 +25,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:16:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:18:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -34,7 +34,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:19:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:21:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -43,7 +43,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:23:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:25:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -52,7 +52,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:27:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:29:9 | LL | let ref mut a @ ( | ^-------- @@ -73,32 +73,54 @@ LL | | ] LL | | ) = (U, [U, U, U]); | |_____^ +error: cannot borrow `a` as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:39:9 + | +LL | let ref mut a @ ( + | ^-------- + | | + | _________first mutable borrow occurs here + | | +LL | | +LL | | ref mut b, + | | --------- another mutable borrow occurs here +LL | | [ +LL | | ref mut c, + | | --------- another mutable borrow occurs here +LL | | ref mut d, + | | --------- another mutable borrow occurs here +LL | | ref e, + | | ----- also borrowed as immutable here +LL | | ] +LL | | ) = (u(), [u(), u(), u()]); + | |_________^ + error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:37:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:49: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:41:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:53: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:45:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:57: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:48:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:60: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: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:53:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:65:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -107,7 +129,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:53:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:65:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -116,7 +138,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:59:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:71:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -125,7 +147,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:59:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:71:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -134,7 +156,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:66:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:78:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -143,7 +165,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:66:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:78:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -152,7 +174,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:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:90:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -161,7 +183,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:90:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -170,7 +192,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:9:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:11:21 | LL | let ref mut a @ ref mut b = U; | ------------^^^^^^^^^ @@ -182,7 +204,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:19:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:21:21 | LL | let ref mut a @ ref mut b = U; | ------------^^^^^^^^^ @@ -194,7 +216,7 @@ LL | *a = U; | ------ first borrow later used here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:37:25 + --> $DIR/borrowck-pat-ref-mut-twice.rs:49: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 @@ -203,7 +225,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:41:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:53: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 @@ -212,7 +234,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:45:18 + --> $DIR/borrowck-pat-ref-mut-twice.rs:57: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 @@ -221,7 +243,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:48:30 + --> $DIR/borrowck-pat-ref-mut-twice.rs:60: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 @@ -230,7 +252,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:66:24 + --> $DIR/borrowck-pat-ref-mut-twice.rs:78:24 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------------^^^^^^^^^- @@ -242,7 +264,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:66:53 + --> $DIR/borrowck-pat-ref-mut-twice.rs:78:53 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ----------------^^^^^^^^^- @@ -254,7 +276,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:78:24 + --> $DIR/borrowck-pat-ref-mut-twice.rs:90:24 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------------^^^^^^^^^- @@ -266,7 +288,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:78:53 + --> $DIR/borrowck-pat-ref-mut-twice.rs:90:53 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ----------------^^^^^^^^^- @@ -277,7 +299,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 28 previous errors +error: aborting due to 29 previous errors Some errors have detailed explanations: E0007, E0382, E0499. For more information about an error, try `rustc --explain E0007`. From 6fa8f4a57b8fb1f2be4b49bb5f87629389252020 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Dec 2019 03:50:55 +0100 Subject: [PATCH 10/17] bindings_after_at: harden tests wrt. contexts & slice_patterns --- .../borrowck-move-and-move.rs | 17 +++ .../borrowck-move-and-move.stderr | 72 ++++++++-- .../borrowck-pat-at-and-box.rs | 59 ++++++++- .../borrowck-pat-at-and-box.stderr | 116 ++++++++++++++-- .../borrowck-pat-by-copy-bindings-in-at.rs | 3 + .../borrowck-pat-ref-both-sides.rs | 3 + .../borrowck-pat-ref-mut-and-ref.rs | 12 ++ .../borrowck-pat-ref-mut-and-ref.stderr | 124 ++++++++++++------ .../borrowck-pat-ref-mut-twice.rs | 15 +++ .../borrowck-pat-ref-mut-twice.stderr | 96 +++++++++----- ...lt-binding-modes-both-sides-independent.rs | 7 + ...inding-modes-both-sides-independent.stderr | 8 +- .../pat-at-same-name-both.rs | 12 ++ .../pat-at-same-name-both.stderr | 41 ++++-- 14 files changed, 477 insertions(+), 108 deletions(-) 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 ba1c8e132f25d..e0931f7e66e18 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 @@ -2,6 +2,7 @@ #![feature(bindings_after_at)] //~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash +#![feature(slice_patterns)] fn main() { struct U; // Not copy! @@ -28,4 +29,20 @@ fn main() { //~| ERROR cannot bind by-move with sub-bindings //~| ERROR use of moved value } + + fn fun(a @ b: U) {} + //~^ ERROR cannot bind by-move with sub-bindings + //~| 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 + } + + match [u(), u(), u(), u()] { + xs @ [_, ys @ .., _] => {} + //~^ ERROR cannot bind by-move with sub-bindings + //~| 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 f08692264e231..605c92e5d8df5 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 @@ -7,37 +7,55 @@ 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:12:9 + --> $DIR/borrowck-move-and-move.rs:13: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:16:9 + --> $DIR/borrowck-move-and-move.rs:17: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:20:9 + --> $DIR/borrowck-move-and-move.rs:21: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:25:9 + --> $DIR/borrowck-move-and-move.rs:26: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:25:21 + --> $DIR/borrowck-move-and-move.rs:26: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:38: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:44: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:33: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:12:13 + --> $DIR/borrowck-move-and-move.rs:13:13 | LL | let a @ b = U; | ----^ - move occurs because value has type `main::U`, which does not implement the `Copy` trait @@ -46,7 +64,7 @@ LL | let a @ b = U; | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:16:17 + --> $DIR/borrowck-move-and-move.rs:17: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 @@ -55,7 +73,7 @@ LL | let a @ (b, c) = (U, U); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:20:17 + --> $DIR/borrowck-move-and-move.rs:21: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 @@ -64,7 +82,7 @@ LL | let a @ (b, c) = (u(), u()); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:25:16 + --> $DIR/borrowck-move-and-move.rs:26:16 | LL | match Ok(U) { | ----- move occurs because value has type `std::result::Result`, which does not implement the `Copy` trait @@ -75,7 +93,7 @@ LL | a @ Ok(b) | a @ Err(b) => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:25:29 + --> $DIR/borrowck-move-and-move.rs:26:29 | LL | match Ok(U) { | ----- move occurs because value has type `std::result::Result`, which does not implement the `Copy` trait @@ -85,7 +103,39 @@ LL | a @ Ok(b) | a @ Err(b) => {} | | value used here after move | value moved here -error: aborting due to 10 previous errors +error[E0382]: use of moved value + --> $DIR/borrowck-move-and-move.rs:38:22 + | +LL | match [u(), u(), u(), u()] { + | -------------------- move occurs because value has type `[main::U; 4]`, which does not implement the `Copy` trait +LL | xs @ [a, .., b] => {} + | -------------^- + | | | + | | value used here after move + | value moved here + +error[E0382]: use of moved value + --> $DIR/borrowck-move-and-move.rs:44:18 + | +LL | match [u(), u(), u(), u()] { + | -------------------- move occurs because value has type `[main::U; 4]`, which does not implement the `Copy` trait +LL | xs @ [_, ys @ .., _] => {} + | ---------^^^^^^^---- + | | | + | | value used here after move + | value moved here + +error[E0382]: use of moved value + --> $DIR/borrowck-move-and-move.rs:33:16 + | +LL | fn fun(a @ b: U) {} + | ----^ + | | | + | | value used here after move + | 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 Some errors have detailed explanations: E0007, E0382. For more information about an error, try `rustc --explain E0007`. 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 cf765f579e002..8512c7f9b696c 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 @@ -9,6 +9,10 @@ struct C; fn c() -> C { C } +struct NC; + +fn nc() -> NC { NC } + fn main() { let a @ box &b = Box::new(&C); //~^ ERROR cannot bind by-move with sub-bindings @@ -18,6 +22,18 @@ fn main() { //~^ ERROR cannot bind by-move with sub-bindings //~| 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 + + fn f2(a @ box b: Box) {} + //~^ ERROR cannot bind by-move with sub-bindings + //~| 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 + let ref a @ box b = Box::new(C); // OK; the type is `Copy`. drop(b); drop(b); @@ -28,9 +44,18 @@ fn main() { drop(b); drop(a); - struct NC; - - fn nc() -> NC { NC } + fn f3(ref a @ box b: Box) { // OK; the type is `Copy`. + drop(b); + drop(b); + drop(a); + } + match Box::new(c()) { + ref a @ box b => { // OK; the type is `Copy`. + drop(b); + drop(b); + drop(a); + } + } let ref a @ box b = Box::new(NC); //~ ERROR cannot bind by-move and by-ref in the same pattern @@ -38,6 +63,18 @@ fn main() { drop(a); drop(b); + fn f4(ref a @ box ref b: Box) { // OK. + drop(a); + drop(b) + } + + match Box::new(nc()) { + ref a @ box ref b => { // OK. + drop(a); + drop(b); + } + } + let ref a @ box ref mut b = Box::new(nc()); //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable let ref a @ box ref mut b = Box::new(NC); @@ -56,4 +93,20 @@ fn main() { //~| 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 `_` as immutable because it is also borrowed as mutable + *a = Box::new(NC); + drop(b); + } + + 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 `_` 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 19cd0b7c1d39a..512e75982cb5e 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 @@ -7,19 +7,25 @@ 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:13:9 + --> $DIR/borrowck-pat-at-and-box.rs:17: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:17:9 + --> $DIR/borrowck-pat-at-and-box.rs:21: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:33: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:35:21 + --> $DIR/borrowck-pat-at-and-box.rs:60:21 | LL | let ref a @ box b = Box::new(NC); | ------------^ @@ -28,7 +34,7 @@ LL | let ref a @ box b = Box::new(NC); | by-ref pattern here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:41:9 + --> $DIR/borrowck-pat-at-and-box.rs:78:9 | LL | let ref a @ box ref mut b = Box::new(nc()); | -----^^^^^^^--------- @@ -37,7 +43,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:43:9 + --> $DIR/borrowck-pat-at-and-box.rs:80:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- @@ -46,7 +52,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:82:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- @@ -55,7 +61,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:48:9 + --> $DIR/borrowck-pat-at-and-box.rs:85:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- @@ -64,7 +70,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:54:9 + --> $DIR/borrowck-pat-at-and-box.rs:91:9 | LL | let ref mut a @ box ref b = Box::new(NC); | ---------^^^^^^^----- @@ -72,8 +78,38 @@ LL | let ref mut a @ box ref b = Box::new(NC); | | immutable borrow occurs here | mutable borrow occurs here +error: cannot borrow `a` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-at-and-box.rs:105:9 + | +LL | ref mut a @ box ref b => { + | ---------^^^^^^^----- + | | | + | | immutable borrow occurs here + | mutable borrow occurs here + +error[E0007]: cannot bind by-move with sub-bindings + --> $DIR/borrowck-pat-at-and-box.rs:25: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:29: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:97:11 + | +LL | fn f5(ref mut a @ box ref b: Box) { + | ---------^^^^^^^----- + | | | + | | immutable borrow occurs here + | mutable borrow occurs here + error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:13:18 + --> $DIR/borrowck-pat-at-and-box.rs:17: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 @@ -82,7 +118,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:17:17 + --> $DIR/borrowck-pat-at-and-box.rs:21: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 @@ -90,8 +126,18 @@ LL | let a @ box b = Box::new(C); | | value used here after move | value moved here +error[E0382]: use of moved value + --> $DIR/borrowck-pat-at-and-box.rs:33:33 + | +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 + error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:48:21 + --> $DIR/borrowck-pat-at-and-box.rs:85:21 | LL | let ref a @ box ref mut b = Box::new(NC); | ------------^^^^^^^^^ @@ -103,7 +149,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:54:25 + --> $DIR/borrowck-pat-at-and-box.rs:91:25 | LL | let ref mut a @ box ref b = Box::new(NC); | ----------------^^^^^ @@ -114,7 +160,51 @@ LL | let ref mut a @ box ref b = Box::new(NC); LL | *a = Box::new(NC); | -- mutable borrow later used here -error: aborting due to 12 previous errors +error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-at-and-box.rs:105:25 + | +LL | ref mut a @ box ref b => { + | ----------------^^^^^ + | | | + | | immutable borrow occurs here + | mutable borrow occurs here +... +LL | *a = Box::new(NC); + | -- mutable borrow later used here + +error[E0382]: use of moved value + --> $DIR/borrowck-pat-at-and-box.rs:25:20 + | +LL | fn f1(a @ box &b: Box<&C>) {} + | ---------^ + | | | + | | value used here after move + | value moved here + | move occurs because value has type `std::boxed::Box<&C>`, which does not implement the `Copy` trait + +error[E0382]: use of moved value + --> $DIR/borrowck-pat-at-and-box.rs:29:19 + | +LL | fn f2(a @ box b: Box) {} + | --------^ + | | | + | | value used here after move + | value moved here + | 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:97:27 + | +LL | fn f5(ref mut a @ box ref b: Box) { + | ----------------^^^^^ + | | | + | | immutable borrow occurs here + | mutable borrow occurs here +... +LL | *a = Box::new(NC); + | -- mutable borrow later used here + +error: aborting due to 22 previous errors Some errors have detailed explanations: E0007, E0009, E0382, E0502. For more information about an error, try `rustc --explain E0007`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs index 4cdbfd636f352..f1dc5dbd12a37 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs @@ -22,9 +22,12 @@ fn main() { let a @ P(b, P(c, d)) = P(mk_c(), P(C, C)); let a @ [b, c] = [C, C]; let a @ [b, .., c] = [C, mk_c(), C]; + let a @ [b, mid @ .., c] = [C, mk_c(), C]; let a @ &(b, c) = &(C, C); let a @ &(b, &P(c, d)) = &(mk_c(), &P(C, C)); + fn foo(a @ [b, mid @ .., c]: [C; 3]) {} + use self::E::*; match L(C) { L(a) | R(a) => { diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs index 3c501ad8f8a50..a09364920f641 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs @@ -5,6 +5,7 @@ #![feature(bindings_after_at)] //~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash +#![feature(slice_patterns)] fn main() { struct U; // Not copy! @@ -27,6 +28,8 @@ fn main() { let _: &U = c; let _: &U = d; + fn f1(ref a @ (ref b, [ref c, ref mid @ .., ref d]): (U, [U; 4])) {} + let a @ (b, [c, d]) = &(u(), [u(), u()]); let _: &(U, [U; 2]) = a; let _: &U = b; 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 54b4e1cae85c9..d2e8219178467 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,5 +1,6 @@ #![feature(bindings_after_at)] //~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash +#![feature(slice_patterns)] enum Option { None, @@ -22,6 +23,17 @@ fn main() { // Prevent promotion: 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 + fn f2(ref mut a @ ref b: U) {} + //~^ 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 + + 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 + let ref a @ ref mut b = U; //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable let ref mut a @ ref b = U; 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 04944c1d528d0..931b3e3c83ca7 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 @@ -7,7 +7,7 @@ LL | #![feature(bindings_after_at)] = note: `#[warn(incomplete_features)]` on by default error: cannot borrow `z` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:12:9 | LL | ref mut z @ &mut Some(ref a) => { | ---------^^^^^^^^^^^^^-----^ @@ -15,8 +15,27 @@ LL | ref mut z @ &mut Some(ref a) => { | | immutable borrow occurs here | mutable borrow occurs here +error: cannot borrow `a` as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:33: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 + +error: cannot borrow `b` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:33:22 + | +LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub + | -----^^^--------- + | | | + | | 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:25:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:37:9 | LL | let ref a @ ref mut b = U; | -----^^^--------- @@ -25,7 +44,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:27:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:39:9 | LL | let ref mut a @ ref b = U; | ---------^^^----- @@ -34,7 +53,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:29:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:41:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -44,7 +63,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:31:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:43:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ @@ -54,7 +73,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:34:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:46:9 | LL | let ref mut a @ ref b = u(); | ---------^^^----- @@ -63,7 +82,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:51:9 | LL | let ref a @ ref mut b = u(); | -----^^^--------- @@ -72,7 +91,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:45:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:57:9 | LL | let ref mut a @ ref b = U; | ---------^^^----- @@ -81,7 +100,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:61:9 | LL | let ref a @ ref mut b = U; | -----^^^--------- @@ -90,7 +109,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:67:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | ---------^^^^^^-----^ @@ -99,7 +118,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:55:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:67:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | ---------^^^^^^^-----^ @@ -108,7 +127,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:64:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----^^^^^^---------^ @@ -117,7 +136,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:64:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----^^^^^^^---------^ @@ -126,7 +145,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:75:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:87:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | -----^^^^^^---------^ @@ -135,7 +154,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:75:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:87:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | -----^^^^^^^---------^ @@ -144,7 +163,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:82:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:94:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ---------^^^^^^-----^ @@ -153,7 +172,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:82:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:94:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ---------^^^^^^^-----^ @@ -162,7 +181,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:89:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:101:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | -----^^^^^^---------^ @@ -171,7 +190,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:89:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:101:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | -----^^^^^^^---------^ @@ -180,7 +199,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:96:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ---------^^^^^^-----^ @@ -189,7 +208,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:96:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ---------^^^^^^^-----^ @@ -198,7 +217,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:103:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:115:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -208,7 +227,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:108:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -218,7 +237,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:115:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -228,7 +247,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:120:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:132:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ @@ -237,8 +256,35 @@ LL | let ref mut a @ (ref b, ref c) = (U, U); | | immutable borrow occurs here | 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:26:11 + | +LL | fn f1(ref a @ ref mut b: U) {} + | -----^^^--------- + | | | + | | mutable borrow occurs here + | 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:28:11 + | +LL | fn f2(ref mut a @ ref b: U) {} + | ---------^^^----- + | | | + | | immutable borrow occurs here + | 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:30:11 + | +LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} + | -----^^^^^^^^^^^----------------^^^^^^^^ + | | | + | | mutable borrow occurs here + | immutable borrow occurs here + error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:31 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:12:31 | LL | ref mut z @ &mut Some(ref a) => { | ----------------------^^^^^- @@ -250,7 +296,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:34:21 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:46:21 | LL | let ref mut a @ ref b = u(); | ------------^^^^^ @@ -262,7 +308,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:39:17 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:51:17 | LL | let ref a @ ref mut b = u(); | --------^^^^^^^^^ @@ -274,7 +320,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:64:20 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:20 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----------^^^^^^^^^- @@ -286,7 +332,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:64:45 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:45 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | ------------^^^^^^^^^- @@ -298,7 +344,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:75:61 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:87:61 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | ^^^^^^ cannot assign @@ -306,7 +352,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:82:61 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:94:61 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ^^^^^^^^^^^ cannot assign @@ -314,7 +360,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:89:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:101: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 @@ -322,7 +368,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:96:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108: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 @@ -330,7 +376,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:108:18 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:18 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | ---------^^^^^^^^^------------ @@ -342,7 +388,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:108:29 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:29 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | --------------------^^^^^^^^^- @@ -354,7 +400,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:115:18 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:18 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | ---------^^^^^^^^^------------ @@ -366,7 +412,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:115:29 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:29 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | --------------------^^^^^^^^^- @@ -377,7 +423,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 38 previous errors +error: aborting due to 43 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 487ac4b852b6e..da032797c3129 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 @@ -2,12 +2,27 @@ #![feature(bindings_after_at)] //~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash +#![feature(slice_patterns)] fn main() { struct U; 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 + fn f2(ref mut a @ ref mut b: U) {} + //~^ ERROR cannot borrow `a` 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 + [ref b @ .., _], + [_, ref mut mid @ ..], + .., + [..], + ] : [[U; 4]; 5] + ) {} + let ref mut a @ ref mut b = U; //~^ ERROR cannot borrow `a` as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time 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 011e18be8b294..365893512e2a3 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 @@ -7,7 +7,7 @@ LL | #![feature(bindings_after_at)] = note: `#[warn(incomplete_features)]` on by default error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:11:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:26:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -16,7 +16,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:15:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:30:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -25,7 +25,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:18:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:33:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -34,7 +34,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:21:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:36:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -43,7 +43,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:25:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:40:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -52,7 +52,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:29:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:44:9 | LL | let ref mut a @ ( | ^-------- @@ -74,7 +74,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:39:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:54:9 | LL | let ref mut a @ ( | ^-------- @@ -96,31 +96,31 @@ LL | | ) = (u(), [u(), u(), u()]); | |_________^ error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:49:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:64: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:53:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:68: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:57:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:72: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:60:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:75: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: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:65:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:80:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -129,7 +129,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:65:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:80:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -138,7 +138,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:71:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:86:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -147,7 +147,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:71:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:86:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -156,7 +156,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:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:93:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -165,7 +165,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:93:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -174,7 +174,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:90:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:105:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -183,7 +183,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:90:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:105:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -191,8 +191,44 @@ 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 +error: cannot borrow `a` as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:12:11 + | +LL | fn f1(ref mut a @ ref mut b: U) {} + | ---------^^^--------- + | | | + | | another mutable borrow occurs here + | first mutable borrow occurs here + +error: cannot borrow `a` as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:14:11 + | +LL | fn f2(ref mut a @ ref mut b: U) {} + | ---------^^^--------- + | | | + | | another mutable borrow occurs here + | first mutable borrow occurs here + +error: cannot borrow `a` as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:17:9 + | +LL | ref mut a @ [ + | ^-------- + | | + | _________first mutable borrow occurs here + | | +LL | | +LL | | [ref b @ .., _], + | | ---------- also borrowed as immutable here +LL | | [_, ref mut mid @ ..], + | | ---------------- another mutable borrow occurs here +LL | | .., +LL | | [..], +LL | | ] : [[U; 4]; 5] + | |_________^ + error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:11:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:26:21 | LL | let ref mut a @ ref mut b = U; | ------------^^^^^^^^^ @@ -204,7 +240,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:21:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:36:21 | LL | let ref mut a @ ref mut b = U; | ------------^^^^^^^^^ @@ -216,7 +252,7 @@ LL | *a = U; | ------ first borrow later used here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:49:25 + --> $DIR/borrowck-pat-ref-mut-twice.rs:64: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 @@ -225,7 +261,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:53:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:68: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 @@ -234,7 +270,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:57:18 + --> $DIR/borrowck-pat-ref-mut-twice.rs:72: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 @@ -243,7 +279,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:60:30 + --> $DIR/borrowck-pat-ref-mut-twice.rs:75: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 @@ -252,7 +288,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:78:24 + --> $DIR/borrowck-pat-ref-mut-twice.rs:93:24 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------------^^^^^^^^^- @@ -264,7 +300,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:78:53 + --> $DIR/borrowck-pat-ref-mut-twice.rs:93:53 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ----------------^^^^^^^^^- @@ -276,7 +312,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:90:24 + --> $DIR/borrowck-pat-ref-mut-twice.rs:105:24 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------------^^^^^^^^^- @@ -288,7 +324,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:90:53 + --> $DIR/borrowck-pat-ref-mut-twice.rs:105:53 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ----------------^^^^^^^^^- @@ -299,7 +335,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 29 previous errors +error: aborting due to 32 previous errors Some errors have detailed explanations: E0007, E0382, E0499. For more information about an error, try `rustc --explain E0007`. 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 df2efd08b9b25..ba2eb7a0383fb 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 @@ -13,6 +13,13 @@ fn main() { struct NotCopy; + fn f1(a @ b: &NotCopy) { // OK + let _: &NotCopy = a; + } + fn f2(ref a @ b: &NotCopy) { + let _: &&NotCopy = a; // Ok + } + let a @ b = &NotCopy; // OK let _: &NotCopy = a; let ref a @ b = &NotCopy; // OK 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 3cd756d11ce5e..0a20a991a9ad5 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 @@ -7,7 +7,7 @@ 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 + --> $DIR/default-binding-modes-both-sides-independent.rs:28:17 | LL | let ref a @ b = NotCopy; | --------^ @@ -16,7 +16,7 @@ LL | let ref a @ b = NotCopy; | by-ref pattern here error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/default-binding-modes-both-sides-independent.rs:22:21 + --> $DIR/default-binding-modes-both-sides-independent.rs:29:21 | LL | let ref mut a @ b = NotCopy; | ------------^ @@ -25,7 +25,7 @@ LL | let ref mut a @ b = NotCopy; | by-ref pattern here error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/default-binding-modes-both-sides-independent.rs:24:20 + --> $DIR/default-binding-modes-both-sides-independent.rs:31:20 | LL | Ok(ref a @ b) | Err(ref a @ b) => {} | --------^ --------^ @@ -36,7 +36,7 @@ LL | Ok(ref a @ b) | Err(ref a @ b) => {} | by-ref 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 + --> $DIR/default-binding-modes-both-sides-independent.rs:35:17 | LL | ref a @ b => {} | --------^ diff --git a/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.rs b/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.rs index 2b5528f49a6bb..f0be901e3da7c 100644 --- a/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.rs +++ b/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.rs @@ -7,6 +7,18 @@ //~^ WARN the feature `or_patterns` is incomplete and may cause the compiler to crash fn main() { + fn f(a @ a @ a: ()) {} + //~^ ERROR identifier `a` is bound more than once in this parameter list + //~| ERROR identifier `a` is bound more than once in this parameter list + + match Ok(0) { + Ok(a @ b @ a) + //~^ ERROR identifier `a` is bound more than once in the same pattern + | Err(a @ b @ a) + //~^ ERROR identifier `a` is bound more than once in the same pattern + => {} + } + 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 diff --git a/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr b/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr index 92a97becc8424..34ae84c2a819b 100644 --- a/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr +++ b/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr @@ -1,35 +1,59 @@ +error[E0415]: identifier `a` is bound more than once in this parameter list + --> $DIR/pat-at-same-name-both.rs:10:14 + | +LL | fn f(a @ a @ a: ()) {} + | ^ used as parameter more than once + +error[E0415]: identifier `a` is bound more than once in this parameter list + --> $DIR/pat-at-same-name-both.rs:10:18 + | +LL | fn f(a @ a @ a: ()) {} + | ^ used as parameter more than once + +error[E0416]: identifier `a` is bound more than once in the same pattern + --> $DIR/pat-at-same-name-both.rs:15:20 + | +LL | Ok(a @ b @ 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:17:23 + | +LL | | Err(a @ b @ 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:13 + --> $DIR/pat-at-same-name-both.rs:22: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 + --> $DIR/pat-at-same-name-both.rs:22: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 + --> $DIR/pat-at-same-name-both.rs:25: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 + --> $DIR/pat-at-same-name-both.rs:27: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 + --> $DIR/pat-at-same-name-both.rs:30: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 + --> $DIR/pat-at-same-name-both.rs:30:26 | LL | let a @ (Ok(a) | Err(a)) = Ok(()); | ^ used in a pattern more than once @@ -48,6 +72,7 @@ warning: the feature `or_patterns` is incomplete and may cause the compiler to c LL | #![feature(or_patterns)] | ^^^^^^^^^^^ -error: aborting due to 6 previous errors +error: aborting due to 10 previous errors -For more information about this error, try `rustc --explain E0416`. +Some errors have detailed explanations: E0415, E0416. +For more information about an error, try `rustc --explain E0415`. From 427b1c33e993b55136ac8323600f9e3c714df3f4 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Dec 2019 04:09:47 +0100 Subject: [PATCH 11/17] clarify bind-by-move-neither-can-livee.. --- ...her-can-live-while-the-other-survives-1.rs | 24 +++++++++ ...can-live-while-the-other-survives-1.stderr | 52 +++++++++++++++++-- 2 files changed, 72 insertions(+), 4 deletions(-) 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 53d16e7ad3ec7..e86db3ab96f9f 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 @@ -1,3 +1,7 @@ +// This test is taken directly from #16053. +// It checks that you cannot use an AND-pattern (`binding @ pat`) +// where one side is by-ref and the other is by-move. + #![feature(bindings_after_at)] //~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash @@ -9,4 +13,24 @@ fn main() { Some(ref _y @ _z) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern None => panic!() } + + let x = Some(X { x: () }); + match x { + Some(_z @ ref _y) => { }, //~ ERROR cannot bind by-move with sub-bindings + //~^ 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!() + } + + let mut x = Some(X { x: () }); + match x { + Some(_z @ ref mut _y) => { }, //~ ERROR cannot bind by-move with sub-bindings + //~^ 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 63866238f565e..658b77ed1abde 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,5 +1,5 @@ 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 + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:5:12 | LL | #![feature(bindings_after_at)] | ^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ 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 + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:13:23 | LL | Some(ref _y @ _z) => { }, | ---------^^ @@ -15,6 +15,50 @@ LL | Some(ref _y @ _z) => { }, | | by-move pattern here | by-ref pattern here -error: aborting due to previous error +error[E0007]: cannot bind by-move with sub-bindings + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:19:14 + | +LL | Some(_z @ ref _y) => { }, + | ^^^^^^^^^^^ binds an already bound by-move value by moving it + +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:26:27 + | +LL | Some(ref mut _y @ _z) => { }, + | -------------^^ + | | | + | | by-move pattern here + | by-ref pattern here + +error[E0007]: cannot bind by-move with sub-bindings + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:32:14 + | +LL | Some(_z @ ref mut _y) => { }, + | ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it + +error[E0382]: borrow of moved value + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:19:19 + | +LL | Some(_z @ ref _y) => { }, + | -----^^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = 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:32:19 + | +LL | Some(_z @ ref mut _y) => { }, + | -----^^^^^^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `X`, which does not implement the `Copy` trait + +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0009`. +Some errors have detailed explanations: E0007, E0009, E0382. +For more information about an error, try `rustc --explain E0007`. From 48f2766522283f20aed612d51dacfb83760b75f0 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Dec 2019 04:12:35 +0100 Subject: [PATCH 12/17] enhance borrowck-pat-by-copy-bindings-in-at --- .../borrowck-pat-by-copy-bindings-in-at.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs index f1dc5dbd12a37..f88286916bc8d 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs @@ -43,4 +43,11 @@ fn main() { drop(a); } } + + match Ok(mk_c()) { + Ok(ref a @ b) | Err(b @ ref a) => { + let _: &C = a; + let _: C = b; + } + } } From e39abcfad905ec8002e826f57656b82475b60c5a Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Dec 2019 04:29:34 +0100 Subject: [PATCH 13/17] harden & split borrowck-pat-at-and-box --- .../borrowck-pat-at-and-box-pass.rs | 77 +++++++++++++++++++ .../borrowck-pat-at-and-box-pass.stderr | 8 ++ .../borrowck-pat-at-and-box.rs | 52 ++++--------- .../borrowck-pat-at-and-box.stderr | 64 +++++++++------ 4 files changed, 139 insertions(+), 62 deletions(-) create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.stderr 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 new file mode 100644 index 0000000000000..d88ca2459bb9a --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs @@ -0,0 +1,77 @@ +// check-pass + +// 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)] +#![feature(slice_patterns)] + +#[derive(Copy, Clone)] +struct C; + +fn c() -> C { C } + +struct NC; + +fn nc() -> NC { NC } + +fn main() { + let ref a @ box b = Box::new(C); // OK; the type is `Copy`. + drop(b); + drop(b); + drop(a); + + let ref a @ box b = Box::new(c()); // OK; the type is `Copy`. + drop(b); + drop(b); + drop(a); + + fn f3(ref a @ box b: Box) { // OK; the type is `Copy`. + drop(b); + drop(b); + drop(a); + } + match Box::new(c()) { + ref a @ box b => { // OK; the type is `Copy`. + drop(b); + drop(b); + drop(a); + } + } + + let ref a @ box ref b = Box::new(NC); // OK. + drop(a); + drop(b); + + fn f4(ref a @ box ref b: Box) { // OK. + drop(a); + drop(b) + } + + match Box::new(nc()) { + ref a @ box ref b => { // OK. + drop(a); + drop(b); + } + } + + match Box::new([Ok(c()), Err(nc()), Ok(c())]) { + box [Ok(a), ref xs @ .., Err(ref b)] => { + let _: C = a; + let _: &[Result; 1] = xs; + let _: &NC = b; + } + _ => {} + } + + match [Ok(Box::new(c())), Err(Box::new(nc())), Ok(Box::new(c())), Ok(Box::new(c()))] { + [Ok(box a), ref xs @ .., Err(box ref b), Err(box ref c)] => { + let _: C = a; + let _: &[Result, Box>; 1] = xs; + let _: &NC = b; + let _: &NC = c; + } + _ => {} + } +} diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.stderr new file mode 100644 index 0000000000000..e981b3428a72b --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.stderr @@ -0,0 +1,8 @@ +warning: the feature `bindings_after_at` is incomplete and may cause the compiler to crash + --> $DIR/borrowck-pat-at-and-box-pass.rs:5:12 + | +LL | #![feature(bindings_after_at)] + | ^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + 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 8512c7f9b696c..32fb962b55c2e 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 @@ -3,6 +3,7 @@ #![feature(bindings_after_at)] //~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash #![feature(box_patterns)] +#![feature(slice_patterns)] #[derive(Copy, Clone)] struct C; @@ -34,47 +35,8 @@ fn main() { //~^ 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); - - let ref a @ box b = Box::new(c()); // OK; the type is `Copy`. - drop(b); - drop(b); - drop(a); - - fn f3(ref a @ box b: Box) { // OK; the type is `Copy`. - drop(b); - drop(b); - drop(a); - } - match Box::new(c()) { - ref a @ box b => { // OK; the type is `Copy`. - drop(b); - drop(b); - drop(a); - } - } - 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); - - fn f4(ref a @ box ref b: Box) { // OK. - drop(a); - drop(b) - } - - match Box::new(nc()) { - ref a @ box ref b => { // OK. - drop(a); - drop(b); - } - } - let ref a @ box ref mut b = Box::new(nc()); //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable let ref a @ box ref mut b = Box::new(NC); @@ -109,4 +71,16 @@ 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 512e75982cb5e..05e80085e6b97 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 @@ -7,25 +7,25 @@ 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:17:9 + --> $DIR/borrowck-pat-at-and-box.rs:18: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:21:9 + --> $DIR/borrowck-pat-at-and-box.rs:22: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:33:25 + --> $DIR/borrowck-pat-at-and-box.rs:34: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:60:21 + --> $DIR/borrowck-pat-at-and-box.rs:38:21 | LL | let ref a @ box b = Box::new(NC); | ------------^ @@ -34,7 +34,7 @@ LL | let ref a @ box b = Box::new(NC); | by-ref pattern here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:78:9 + --> $DIR/borrowck-pat-at-and-box.rs:40:9 | LL | let ref a @ box ref mut b = Box::new(nc()); | -----^^^^^^^--------- @@ -43,7 +43,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:80:9 + --> $DIR/borrowck-pat-at-and-box.rs:42:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- @@ -52,7 +52,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:82:9 + --> $DIR/borrowck-pat-at-and-box.rs:44:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- @@ -61,7 +61,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:85:9 + --> $DIR/borrowck-pat-at-and-box.rs:47:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- @@ -70,7 +70,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:91:9 + --> $DIR/borrowck-pat-at-and-box.rs:53:9 | LL | let ref mut a @ box ref b = Box::new(NC); | ---------^^^^^^^----- @@ -79,7 +79,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:105:9 + --> $DIR/borrowck-pat-at-and-box.rs:67:9 | LL | ref mut a @ box ref b => { | ---------^^^^^^^----- @@ -87,20 +87,38 @@ 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:76: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:82: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:25:11 + --> $DIR/borrowck-pat-at-and-box.rs:26: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:29:11 + --> $DIR/borrowck-pat-at-and-box.rs:30: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:97:11 + --> $DIR/borrowck-pat-at-and-box.rs:59:11 | LL | fn f5(ref mut a @ box ref b: Box) { | ---------^^^^^^^----- @@ -109,7 +127,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:17:18 + --> $DIR/borrowck-pat-at-and-box.rs:18: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 @@ -118,7 +136,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:21:17 + --> $DIR/borrowck-pat-at-and-box.rs:22: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 @@ -127,7 +145,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:33:33 + --> $DIR/borrowck-pat-at-and-box.rs:34:33 | LL | match Box::new(C) { a @ box b => {} } | ----------- --------^ @@ -137,7 +155,7 @@ LL | match Box::new(C) { a @ box b => {} } | move occurs because value has type `std::boxed::Box`, which does not implement the `Copy` trait error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:85:21 + --> $DIR/borrowck-pat-at-and-box.rs:47:21 | LL | let ref a @ box ref mut b = Box::new(NC); | ------------^^^^^^^^^ @@ -149,7 +167,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:91:25 + --> $DIR/borrowck-pat-at-and-box.rs:53:25 | LL | let ref mut a @ box ref b = Box::new(NC); | ----------------^^^^^ @@ -161,7 +179,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:105:25 + --> $DIR/borrowck-pat-at-and-box.rs:67:25 | LL | ref mut a @ box ref b => { | ----------------^^^^^ @@ -173,7 +191,7 @@ LL | *a = Box::new(NC); | -- mutable borrow later used here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:25:20 + --> $DIR/borrowck-pat-at-and-box.rs:26:20 | LL | fn f1(a @ box &b: Box<&C>) {} | ---------^ @@ -183,7 +201,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:29:19 + --> $DIR/borrowck-pat-at-and-box.rs:30:19 | LL | fn f2(a @ box b: Box) {} | --------^ @@ -193,7 +211,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:97:27 + --> $DIR/borrowck-pat-at-and-box.rs:59:27 | LL | fn f5(ref mut a @ box ref b: Box) { | ----------------^^^^^ @@ -204,7 +222,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 22 previous errors +error: aborting due to 24 previous errors Some errors have detailed explanations: E0007, E0009, E0382, E0502. For more information about an error, try `rustc --explain E0007`. From c37bd26eaa350d2837dfc50412a823142405307f Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Dec 2019 04:40:26 +0100 Subject: [PATCH 14/17] Test that `_ @ subpat` is syntactically rejected. --- .../wild-before-at-syntactically-rejected.rs | 16 +++++++ ...ld-before-at-syntactically-rejected.stderr | 43 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 src/test/ui/pattern/bindings-after-at/wild-before-at-syntactically-rejected.rs create mode 100644 src/test/ui/pattern/bindings-after-at/wild-before-at-syntactically-rejected.stderr diff --git a/src/test/ui/pattern/bindings-after-at/wild-before-at-syntactically-rejected.rs b/src/test/ui/pattern/bindings-after-at/wild-before-at-syntactically-rejected.rs new file mode 100644 index 0000000000000..50ac0ef27834e --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/wild-before-at-syntactically-rejected.rs @@ -0,0 +1,16 @@ +// Here we check that `_ @ sub` is syntactically invalid +// and comes with a nice actionable suggestion. + +fn main() {} + +#[cfg(FALSE)] +fn wild_before_at_is_bad_syntax() { + let _ @ a = 0; + //~^ ERROR pattern on wrong side of `@` + let _ @ ref a = 0; + //~^ ERROR pattern on wrong side of `@` + let _ @ ref mut a = 0; + //~^ ERROR pattern on wrong side of `@` + let _ @ (a, .., b) = (0, 1, 2, 3); + //~^ ERROR left-hand side of `@` must be a binding +} diff --git a/src/test/ui/pattern/bindings-after-at/wild-before-at-syntactically-rejected.stderr b/src/test/ui/pattern/bindings-after-at/wild-before-at-syntactically-rejected.stderr new file mode 100644 index 0000000000000..2f45415844d86 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/wild-before-at-syntactically-rejected.stderr @@ -0,0 +1,43 @@ +error: pattern on wrong side of `@` + --> $DIR/wild-before-at-syntactically-rejected.rs:8:9 + | +LL | let _ @ a = 0; + | -^^^- + | | | + | | binding on the right, should be on the left + | pattern on the left, should be on the right + | help: switch the order: `a @ _` + +error: pattern on wrong side of `@` + --> $DIR/wild-before-at-syntactically-rejected.rs:10:9 + | +LL | let _ @ ref a = 0; + | -^^^----- + | | | + | | binding on the right, should be on the left + | pattern on the left, should be on the right + | help: switch the order: `ref a @ _` + +error: pattern on wrong side of `@` + --> $DIR/wild-before-at-syntactically-rejected.rs:12:9 + | +LL | let _ @ ref mut a = 0; + | -^^^--------- + | | | + | | binding on the right, should be on the left + | pattern on the left, should be on the right + | help: switch the order: `ref mut a @ _` + +error: left-hand side of `@` must be a binding + --> $DIR/wild-before-at-syntactically-rejected.rs:14:9 + | +LL | let _ @ (a, .., b) = (0, 1, 2, 3); + | -^^^---------- + | | | + | | also a pattern + | interpreted as a pattern, not a binding + | + = note: bindings are `x`, `mut x`, `ref x`, and `ref mut x` + +error: aborting due to 4 previous errors + From 8846a6b6bb2dc9d776335fda01f68c9c1c7b94e6 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Dec 2019 04:52:13 +0100 Subject: [PATCH 15/17] Test that nested type ascription is banned. --- ...d-type-ascription-syntactically-invalid.rs | 35 +++++++++++++++++++ ...pe-ascription-syntactically-invalid.stderr | 34 ++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 src/test/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.rs create mode 100644 src/test/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.stderr diff --git a/src/test/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.rs b/src/test/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.rs new file mode 100644 index 0000000000000..493f1cbb47031 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.rs @@ -0,0 +1,35 @@ +// Here we check that type ascription is syntactically invalid when +// not in the top position of a ascribing a let binding or function parameter. + +#![feature(bindings_after_at)] +//~^ WARN the feature `bindings_after_at` is incomplete + +// This has no effect. +// We include it to demonstrate that this is the case: +#![feature(type_ascription)] + +fn main() {} + +fn _ok() { + let _a @ _b: u8 = 0; // OK. + fn _f(_a @ _b: u8) {} // OK. +} + +#[cfg(FALSE)] +fn case_1() { + let a: u8 @ b = 0; + //~^ ERROR expected one of `!` +} + +#[cfg(FALSE)] +fn case_2() { + let a @ (b: u8); + //~^ ERROR expected one of `!` + //~| ERROR expected one of `)` +} + +#[cfg(FALSE)] +fn case_3() { + let a: T1 @ Outer(b: T2); + //~^ ERROR expected one of `!` +} diff --git a/src/test/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.stderr b/src/test/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.stderr new file mode 100644 index 0000000000000..cdd1574f2b6f7 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.stderr @@ -0,0 +1,34 @@ +error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `=`, found `@` + --> $DIR/nested-type-ascription-syntactically-invalid.rs:20:15 + | +LL | let a: u8 @ b = 0; + | ^ expected one of 7 possible tokens + +error: expected one of `)`, `,`, `@`, or `|`, found `:` + --> $DIR/nested-type-ascription-syntactically-invalid.rs:26:15 + | +LL | let a @ (b: u8); + | ^ expected one of `)`, `,`, `@`, or `|` + +error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `=`, found `)` + --> $DIR/nested-type-ascription-syntactically-invalid.rs:26:19 + | +LL | let a @ (b: u8); + | ^ expected one of 7 possible tokens + +error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `=`, found `@` + --> $DIR/nested-type-ascription-syntactically-invalid.rs:33:15 + | +LL | let a: T1 @ Outer(b: T2); + | ^ expected one of 7 possible tokens + +warning: the feature `bindings_after_at` is incomplete and may cause the compiler to crash + --> $DIR/nested-type-ascription-syntactically-invalid.rs:4:12 + | +LL | #![feature(bindings_after_at)] + | ^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + +error: aborting due to 4 previous errors + From 371446cc50ca5da670e8b2b66d08633f39a33a04 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Dec 2019 05:06:54 +0100 Subject: [PATCH 16/17] Remove `bindings_after_at` from `INCOMPLETE_FEATURES`. --- src/librustc_feature/active.rs | 1 - src/test/ui/error-codes/E0007.rs | 1 - src/test/ui/error-codes/E0007.stderr | 12 +-- ...her-can-live-while-the-other-survives-1.rs | 1 - ...can-live-while-the-other-survives-1.stderr | 20 ++-- .../bind-by-move-no-subbindings-fun-param.rs | 1 - ...nd-by-move-no-subbindings-fun-param.stderr | 12 +-- .../borrowck-move-and-move.rs | 1 - .../borrowck-move-and-move.stderr | 40 ++++---- .../borrowck-pat-at-and-box-pass.rs | 1 - .../borrowck-pat-at-and-box-pass.stderr | 8 -- .../borrowck-pat-at-and-box.rs | 1 - .../borrowck-pat-at-and-box.stderr | 56 +++++------ .../borrowck-pat-by-copy-bindings-in-at.rs | 1 - ...borrowck-pat-by-copy-bindings-in-at.stderr | 8 -- .../borrowck-pat-by-move-and-ref.rs | 1 - .../borrowck-pat-by-move-and-ref.stderr | 10 +- .../borrowck-pat-ref-both-sides.rs | 1 - .../borrowck-pat-ref-both-sides.stderr | 8 -- .../borrowck-pat-ref-mut-and-ref.rs | 1 - .../borrowck-pat-ref-mut-and-ref.stderr | 94 +++++++++---------- .../borrowck-pat-ref-mut-twice.rs | 1 - .../borrowck-pat-ref-mut-twice.stderr | 72 +++++++------- .../bindings-after-at/copy-and-move-mixed.rs | 1 - .../copy-and-move-mixed.stderr | 20 ++-- ...lt-binding-modes-both-sides-independent.rs | 1 - ...inding-modes-both-sides-independent.stderr | 16 +--- .../bindings-after-at/nested-patterns.rs | 1 - .../bindings-after-at/nested-patterns.stderr | 8 -- ...d-type-ascription-syntactically-invalid.rs | 1 - ...pe-ascription-syntactically-invalid.stderr | 16 +--- .../pat-at-same-name-both.rs | 1 - .../pat-at-same-name-both.stderr | 32 +++---- 33 files changed, 153 insertions(+), 296 deletions(-) delete mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.stderr delete mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.stderr delete mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.stderr delete mode 100644 src/test/ui/pattern/bindings-after-at/nested-patterns.stderr diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 06dbc8faf1dab..36664af8782f4 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -558,5 +558,4 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[ sym::or_patterns, sym::let_chains, sym::raw_dylib, - sym::bindings_after_at, ]; diff --git a/src/test/ui/error-codes/E0007.rs b/src/test/ui/error-codes/E0007.rs index 4f7fc0dc2326c..022ac5fc113dd 100644 --- a/src/test/ui/error-codes/E0007.rs +++ b/src/test/ui/error-codes/E0007.rs @@ -1,5 +1,4 @@ #![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()); diff --git a/src/test/ui/error-codes/E0007.stderr b/src/test/ui/error-codes/E0007.stderr index d7b8050c3a4cd..31af9171725bb 100644 --- a/src/test/ui/error-codes/E0007.stderr +++ b/src/test/ui/error-codes/E0007.stderr @@ -1,19 +1,11 @@ -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:7:9 + --> $DIR/E0007.rs:6:9 | LL | op_string @ Some(s) => {}, | ^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it error[E0382]: use of moved value - --> $DIR/E0007.rs:7:26 + --> $DIR/E0007.rs:6:26 | LL | let x = Some("s".to_string()); | - move occurs because `x` has type `std::option::Option`, which does not implement the `Copy` trait 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 e86db3ab96f9f..75d7af58e706d 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,7 +3,6 @@ // where one side is by-ref and the other is by-move. #![feature(bindings_after_at)] -//~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash struct X { x: () } 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 658b77ed1abde..22d62ff4f003f 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,13 +1,5 @@ -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:5: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:13:23 + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:12:23 | LL | Some(ref _y @ _z) => { }, | ---------^^ @@ -16,13 +8,13 @@ LL | Some(ref _y @ _z) => { }, | by-ref pattern here error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:19:14 + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:18:14 | LL | Some(_z @ ref _y) => { }, | ^^^^^^^^^^^ binds an already bound by-move value by moving it 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:26:27 + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:25:27 | LL | Some(ref mut _y @ _z) => { }, | -------------^^ @@ -31,13 +23,13 @@ LL | Some(ref mut _y @ _z) => { }, | by-ref pattern here error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:32:14 + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:31:14 | LL | Some(_z @ ref mut _y) => { }, | ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it error[E0382]: borrow of moved value - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:19:19 + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:18:19 | LL | Some(_z @ ref _y) => { }, | -----^^^^^^ @@ -48,7 +40,7 @@ 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:32:19 + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:31:19 | LL | Some(_z @ ref mut _y) => { }, | -----^^^^^^^^^^ 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 bfaab69a776b6..86fb04e2edf5b 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,7 +1,6 @@ // See issue #12534. #![feature(bindings_after_at)] -//~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash fn main() {} 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 15b0d5e2cb448..b039708fd3e0a 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,19 +1,11 @@ -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 + --> $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:10:12 + --> $DIR/bind-by-move-no-subbindings-fun-param.rs:9:12 | LL | fn f(a @ A(u): A) -> Box { | ------^- 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 e0931f7e66e18..1d9f341c5146a 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,7 +1,6 @@ // 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 #![feature(slice_patterns)] fn main() { 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 605c92e5d8df5..f3f8fd655ce0c 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,61 +1,53 @@ -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:13:9 + --> $DIR/borrowck-move-and-move.rs:12: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:17:9 + --> $DIR/borrowck-move-and-move.rs:16: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:21:9 + --> $DIR/borrowck-move-and-move.rs:20: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:26:9 + --> $DIR/borrowck-move-and-move.rs:25: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:26:21 + --> $DIR/borrowck-move-and-move.rs:25: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:38:9 + --> $DIR/borrowck-move-and-move.rs:37: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:44:9 + --> $DIR/borrowck-move-and-move.rs:43: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:33:12 + --> $DIR/borrowck-move-and-move.rs:32: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:13:13 + --> $DIR/borrowck-move-and-move.rs:12:13 | LL | let a @ b = U; | ----^ - move occurs because value has type `main::U`, which does not implement the `Copy` trait @@ -64,7 +56,7 @@ LL | let a @ b = U; | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:17: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 @@ -73,7 +65,7 @@ LL | let a @ (b, c) = (U, U); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:21:17 + --> $DIR/borrowck-move-and-move.rs:20: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 @@ -82,7 +74,7 @@ LL | let a @ (b, c) = (u(), u()); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:26:16 + --> $DIR/borrowck-move-and-move.rs:25:16 | LL | match Ok(U) { | ----- move occurs because value has type `std::result::Result`, which does not implement the `Copy` trait @@ -93,7 +85,7 @@ LL | a @ Ok(b) | a @ Err(b) => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:26:29 + --> $DIR/borrowck-move-and-move.rs:25:29 | LL | match Ok(U) { | ----- move occurs because value has type `std::result::Result`, which does not implement the `Copy` trait @@ -104,7 +96,7 @@ LL | a @ Ok(b) | a @ Err(b) => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:38:22 + --> $DIR/borrowck-move-and-move.rs:37:22 | LL | match [u(), u(), u(), u()] { | -------------------- move occurs because value has type `[main::U; 4]`, which does not implement the `Copy` trait @@ -115,7 +107,7 @@ LL | xs @ [a, .., b] => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:44:18 + --> $DIR/borrowck-move-and-move.rs:43:18 | LL | match [u(), u(), u(), u()] { | -------------------- move occurs because value has type `[main::U; 4]`, which does not implement the `Copy` trait @@ -126,7 +118,7 @@ LL | xs @ [_, ys @ .., _] => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:33:16 + --> $DIR/borrowck-move-and-move.rs:32:16 | LL | fn fun(a @ b: U) {} | ----^ 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 d88ca2459bb9a..afac8d990b474 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,7 +3,6 @@ // 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)] #![feature(slice_patterns)] diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.stderr deleted file mode 100644 index e981b3428a72b..0000000000000 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.stderr +++ /dev/null @@ -1,8 +0,0 @@ -warning: the feature `bindings_after_at` is incomplete and may cause the compiler to crash - --> $DIR/borrowck-pat-at-and-box-pass.rs:5:12 - | -LL | #![feature(bindings_after_at)] - | ^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - 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 32fb962b55c2e..fce31409e16c4 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,7 +1,6 @@ // 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)] #![feature(slice_patterns)] 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 05e80085e6b97..5772fadd1e741 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,31 +1,23 @@ -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:18:9 + --> $DIR/borrowck-pat-at-and-box.rs:17: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:22:9 + --> $DIR/borrowck-pat-at-and-box.rs:21: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:34:25 + --> $DIR/borrowck-pat-at-and-box.rs:33: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:38:21 + --> $DIR/borrowck-pat-at-and-box.rs:37:21 | LL | let ref a @ box b = Box::new(NC); | ------------^ @@ -34,7 +26,7 @@ LL | let ref a @ box b = Box::new(NC); | by-ref pattern 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:39:9 | LL | let ref a @ box ref mut b = Box::new(nc()); | -----^^^^^^^--------- @@ -43,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:42:9 + --> $DIR/borrowck-pat-at-and-box.rs:41:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- @@ -52,7 +44,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:44:9 + --> $DIR/borrowck-pat-at-and-box.rs:43:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- @@ -61,7 +53,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:47:9 + --> $DIR/borrowck-pat-at-and-box.rs:46:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- @@ -70,7 +62,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:53:9 + --> $DIR/borrowck-pat-at-and-box.rs:52:9 | LL | let ref mut a @ box ref b = Box::new(NC); | ---------^^^^^^^----- @@ -79,7 +71,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:67:9 + --> $DIR/borrowck-pat-at-and-box.rs:66:9 | LL | ref mut a @ box ref b => { | ---------^^^^^^^----- @@ -88,7 +80,7 @@ LL | ref mut a @ box ref b => { | mutable borrow occurs here error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/borrowck-pat-at-and-box.rs:76:38 + --> $DIR/borrowck-pat-at-and-box.rs:75:38 | LL | box [Ok(a), ref xs @ .., Err(b)] => {} | ----------- ^ by-move pattern here @@ -96,7 +88,7 @@ LL | box [Ok(a), ref xs @ .., Err(b)] => {} | by-ref pattern here error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/borrowck-pat-at-and-box.rs:82:46 + --> $DIR/borrowck-pat-at-and-box.rs:81:46 | LL | [Ok(box ref a), ref xs @ .., Err(box b), Err(box ref mut c)] => {} | ----- ----------- ^ --------- by-ref pattern here @@ -106,19 +98,19 @@ LL | [Ok(box ref a), ref xs @ .., Err(box b), Err(box ref mut c)] => {} | by-ref pattern here error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:26:11 + --> $DIR/borrowck-pat-at-and-box.rs:25: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:30:11 + --> $DIR/borrowck-pat-at-and-box.rs:29: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:59:11 + --> $DIR/borrowck-pat-at-and-box.rs:58:11 | LL | fn f5(ref mut a @ box ref b: Box) { | ---------^^^^^^^----- @@ -127,7 +119,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:18:18 + --> $DIR/borrowck-pat-at-and-box.rs:17: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 @@ -136,7 +128,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:22:17 + --> $DIR/borrowck-pat-at-and-box.rs:21: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 @@ -145,7 +137,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:34:33 + --> $DIR/borrowck-pat-at-and-box.rs:33:33 | LL | match Box::new(C) { a @ box b => {} } | ----------- --------^ @@ -155,7 +147,7 @@ LL | match Box::new(C) { a @ box b => {} } | move occurs because value has type `std::boxed::Box`, which does not implement the `Copy` trait error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:47:21 + --> $DIR/borrowck-pat-at-and-box.rs:46:21 | LL | let ref a @ box ref mut b = Box::new(NC); | ------------^^^^^^^^^ @@ -167,7 +159,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:53:25 + --> $DIR/borrowck-pat-at-and-box.rs:52:25 | LL | let ref mut a @ box ref b = Box::new(NC); | ----------------^^^^^ @@ -179,7 +171,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:67:25 + --> $DIR/borrowck-pat-at-and-box.rs:66:25 | LL | ref mut a @ box ref b => { | ----------------^^^^^ @@ -191,7 +183,7 @@ LL | *a = Box::new(NC); | -- mutable borrow later used here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:26:20 + --> $DIR/borrowck-pat-at-and-box.rs:25:20 | LL | fn f1(a @ box &b: Box<&C>) {} | ---------^ @@ -201,7 +193,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:30:19 + --> $DIR/borrowck-pat-at-and-box.rs:29:19 | LL | fn f2(a @ box b: Box) {} | --------^ @@ -211,7 +203,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:59:27 + --> $DIR/borrowck-pat-at-and-box.rs:58:27 | LL | fn f5(ref mut a @ box ref b: Box) { | ----------------^^^^^ diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs index f88286916bc8d..be19e5f2a85ca 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs @@ -4,7 +4,6 @@ #![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; diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.stderr deleted file mode 100644 index e5bbc112bb138..0000000000000 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.stderr +++ /dev/null @@ -1,8 +0,0 @@ -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 - 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 5852e30722909..abe5ed81b71a2 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,5 +1,4 @@ #![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()) { 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 36dc1b2879263..1f70a6c437e92 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,13 +1,5 @@ -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 + --> $DIR/borrowck-pat-by-move-and-ref.rs:5:34 | LL | ref op_string_ref @ Some(s) => {}, | -------------------------^- diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs index a09364920f641..edf9fb3145890 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs @@ -4,7 +4,6 @@ // 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 #![feature(slice_patterns)] fn main() { diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.stderr deleted file mode 100644 index 7a500df77cd89..0000000000000 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.stderr +++ /dev/null @@ -1,8 +0,0 @@ -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 - 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 d2e8219178467..88eda9afec7eb 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,5 +1,4 @@ #![feature(bindings_after_at)] -//~^ WARN the feature `bindings_after_at` is incomplete and may cause the compiler to crash #![feature(slice_patterns)] enum Option { 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 931b3e3c83ca7..b068a6125b670 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,13 +1,5 @@ -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: cannot borrow `z` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:12:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:9 | LL | ref mut z @ &mut Some(ref a) => { | ---------^^^^^^^^^^^^^-----^ @@ -16,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:33:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:32:9 | LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | ---------^^^^-----------------^ @@ -26,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:33:22 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:32:22 | LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | -----^^^--------- @@ -35,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:37:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:36:9 | LL | let ref a @ ref mut b = U; | -----^^^--------- @@ -44,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:39:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:38:9 | LL | let ref mut a @ ref b = U; | ---------^^^----- @@ -53,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:41:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:40:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -63,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:43:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:42:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ @@ -73,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:46:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:45:9 | LL | let ref mut a @ ref b = u(); | ---------^^^----- @@ -82,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:51:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:50:9 | LL | let ref a @ ref mut b = u(); | -----^^^--------- @@ -91,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:57:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:56:9 | LL | let ref mut a @ ref b = U; | ---------^^^----- @@ -100,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:61:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:60:9 | LL | let ref a @ ref mut b = U; | -----^^^--------- @@ -109,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:67:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:66:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | ---------^^^^^^-----^ @@ -118,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:67:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:66:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | ---------^^^^^^^-----^ @@ -127,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:76:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----^^^^^^---------^ @@ -136,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:76:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----^^^^^^^---------^ @@ -145,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:87:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:86:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | -----^^^^^^---------^ @@ -154,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:87:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:86:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | -----^^^^^^^---------^ @@ -163,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:94:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:93:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ---------^^^^^^-----^ @@ -172,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:94:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:93:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ---------^^^^^^^-----^ @@ -181,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:101:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:100:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | -----^^^^^^---------^ @@ -190,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:101:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:100:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | -----^^^^^^^---------^ @@ -199,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:108:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ---------^^^^^^-----^ @@ -208,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:108:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ---------^^^^^^^-----^ @@ -217,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:114:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -227,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:119:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -237,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:126:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -247,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:131:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ @@ -257,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:26:11 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:25:11 | LL | fn f1(ref a @ ref mut b: U) {} | -----^^^--------- @@ -266,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:28:11 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:27:11 | LL | fn f2(ref mut a @ ref b: U) {} | ---------^^^----- @@ -275,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:30: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]) {} | -----^^^^^^^^^^^----------------^^^^^^^^ @@ -284,7 +276,7 @@ LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} | immutable borrow occurs here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:12:31 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:31 | LL | ref mut z @ &mut Some(ref a) => { | ----------------------^^^^^- @@ -296,7 +288,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:46:21 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:45:21 | LL | let ref mut a @ ref b = u(); | ------------^^^^^ @@ -308,7 +300,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:51:17 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:50:17 | LL | let ref a @ ref mut b = u(); | --------^^^^^^^^^ @@ -320,7 +312,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:76:20 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75:20 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----------^^^^^^^^^- @@ -332,7 +324,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:76:45 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75:45 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | ------------^^^^^^^^^- @@ -344,7 +336,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:87:61 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:86:61 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | ^^^^^^ cannot assign @@ -352,7 +344,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:94:61 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:93:61 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ^^^^^^^^^^^ cannot assign @@ -360,7 +352,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:101:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:100: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 +360,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:108:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107: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 +368,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:119:18 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | ---------^^^^^^^^^------------ @@ -388,7 +380,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:119:29 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | --------------------^^^^^^^^^- @@ -400,7 +392,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:126:18 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | ---------^^^^^^^^^------------ @@ -412,7 +404,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:126:29 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | --------------------^^^^^^^^^- 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 da032797c3129..6b8b7545e687d 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,7 +1,6 @@ // 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 #![feature(slice_patterns)] fn main() { 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 365893512e2a3..1b5e6c7411703 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,13 +1,5 @@ -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: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:26:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:25:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -16,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:30:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:29:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -25,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:33:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:32:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -34,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:36:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:35:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -43,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:40:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:39:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -52,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:44:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:43:9 | LL | let ref mut a @ ( | ^-------- @@ -74,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:54:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:53:9 | LL | let ref mut a @ ( | ^-------- @@ -96,31 +88,31 @@ LL | | ) = (u(), [u(), u(), u()]); | |_________^ error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:64:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:63: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:68:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:67: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:72:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:71: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:75:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:74: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: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:80:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:79:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -129,7 +121,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:80:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:79:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -138,7 +130,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:86:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:85:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -147,7 +139,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:86:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:85:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -156,7 +148,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:93:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:92:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -165,7 +157,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:93:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:92:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -174,7 +166,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:105:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:104:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -183,7 +175,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:105:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:104:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -192,7 +184,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:12:11 + --> $DIR/borrowck-pat-ref-mut-twice.rs:11:11 | LL | fn f1(ref mut a @ ref mut b: U) {} | ---------^^^--------- @@ -201,7 +193,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:14:11 + --> $DIR/borrowck-pat-ref-mut-twice.rs:13:11 | LL | fn f2(ref mut a @ ref mut b: U) {} | ---------^^^--------- @@ -210,7 +202,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:17:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:16:9 | LL | ref mut a @ [ | ^-------- @@ -228,7 +220,7 @@ LL | | ] : [[U; 4]; 5] | |_________^ error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:26:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:25:21 | LL | let ref mut a @ ref mut b = U; | ------------^^^^^^^^^ @@ -240,7 +232,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:36:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:35:21 | LL | let ref mut a @ ref mut b = U; | ------------^^^^^^^^^ @@ -252,7 +244,7 @@ LL | *a = U; | ------ first borrow later used here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:64:25 + --> $DIR/borrowck-pat-ref-mut-twice.rs:63: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 @@ -261,7 +253,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:68:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:67: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 @@ -270,7 +262,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:72:18 + --> $DIR/borrowck-pat-ref-mut-twice.rs:71: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 @@ -279,7 +271,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:75:30 + --> $DIR/borrowck-pat-ref-mut-twice.rs:74: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 @@ -288,7 +280,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:93:24 + --> $DIR/borrowck-pat-ref-mut-twice.rs:92:24 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------------^^^^^^^^^- @@ -300,7 +292,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:93:53 + --> $DIR/borrowck-pat-ref-mut-twice.rs:92:53 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ----------------^^^^^^^^^- @@ -312,7 +304,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:105:24 + --> $DIR/borrowck-pat-ref-mut-twice.rs:104:24 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------------^^^^^^^^^- @@ -324,7 +316,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:105:53 + --> $DIR/borrowck-pat-ref-mut-twice.rs:104:53 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ----------------^^^^^^^^^- 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 b517ed71c7344..db5aabc7a1453 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,7 +1,6 @@ // 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; 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 89993a48e193e..cfc35d6c32a72 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,31 +1,23 @@ -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 + --> $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:16:9 + --> $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:16:19 + --> $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:12:19 + --> $DIR/copy-and-move-mixed.rs:11:19 | LL | let a @ NC(b, c) = NC(C, C); | ----------^- -------- move occurs because value has type `NC`, which does not implement the `Copy` trait @@ -34,7 +26,7 @@ LL | let a @ NC(b, c) = NC(C, C); | value moved here error[E0382]: use of moved value - --> $DIR/copy-and-move-mixed.rs:16:19 + --> $DIR/copy-and-move-mixed.rs:15:19 | LL | let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C)); | ----------^^^^^^^^^^^^- --------------- move occurs because value has type `NC>`, which does not implement the `Copy` trait @@ -43,7 +35,7 @@ LL | let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C)); | value moved here error[E0382]: use of moved value - --> $DIR/copy-and-move-mixed.rs:16:29 + --> $DIR/copy-and-move-mixed.rs:15:29 | LL | let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C)); | ----------^- 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 ba2eb7a0383fb..1127d114145cd 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,7 +8,6 @@ // 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; 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 0a20a991a9ad5..b6709a8a40e23 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,13 +1,5 @@ -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:28:17 + --> $DIR/default-binding-modes-both-sides-independent.rs:27:17 | LL | let ref a @ b = NotCopy; | --------^ @@ -16,7 +8,7 @@ LL | let ref a @ b = NotCopy; | by-ref pattern here error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/default-binding-modes-both-sides-independent.rs:29:21 + --> $DIR/default-binding-modes-both-sides-independent.rs:28:21 | LL | let ref mut a @ b = NotCopy; | ------------^ @@ -25,7 +17,7 @@ LL | let ref mut a @ b = NotCopy; | by-ref pattern here error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/default-binding-modes-both-sides-independent.rs:31:20 + --> $DIR/default-binding-modes-both-sides-independent.rs:30:20 | LL | Ok(ref a @ b) | Err(ref a @ b) => {} | --------^ --------^ @@ -36,7 +28,7 @@ LL | Ok(ref a @ b) | Err(ref a @ b) => {} | by-ref pattern here error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/default-binding-modes-both-sides-independent.rs:35:17 + --> $DIR/default-binding-modes-both-sides-independent.rs:34:17 | LL | ref a @ b => {} | --------^ diff --git a/src/test/ui/pattern/bindings-after-at/nested-patterns.rs b/src/test/ui/pattern/bindings-after-at/nested-patterns.rs index 63e07842b1ab0..6296652c11212 100644 --- a/src/test/ui/pattern/bindings-after-at/nested-patterns.rs +++ b/src/test/ui/pattern/bindings-after-at/nested-patterns.rs @@ -1,7 +1,6 @@ // 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 } diff --git a/src/test/ui/pattern/bindings-after-at/nested-patterns.stderr b/src/test/ui/pattern/bindings-after-at/nested-patterns.stderr deleted file mode 100644 index 1864a8e2af733..0000000000000 --- a/src/test/ui/pattern/bindings-after-at/nested-patterns.stderr +++ /dev/null @@ -1,8 +0,0 @@ -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 - diff --git a/src/test/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.rs b/src/test/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.rs index 493f1cbb47031..dbec2f135fbbe 100644 --- a/src/test/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.rs +++ b/src/test/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.rs @@ -2,7 +2,6 @@ // not in the top position of a ascribing a let binding or function parameter. #![feature(bindings_after_at)] -//~^ WARN the feature `bindings_after_at` is incomplete // This has no effect. // We include it to demonstrate that this is the case: diff --git a/src/test/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.stderr b/src/test/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.stderr index cdd1574f2b6f7..1e957ed06892c 100644 --- a/src/test/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.stderr +++ b/src/test/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.stderr @@ -1,34 +1,26 @@ error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `=`, found `@` - --> $DIR/nested-type-ascription-syntactically-invalid.rs:20:15 + --> $DIR/nested-type-ascription-syntactically-invalid.rs:19:15 | LL | let a: u8 @ b = 0; | ^ expected one of 7 possible tokens error: expected one of `)`, `,`, `@`, or `|`, found `:` - --> $DIR/nested-type-ascription-syntactically-invalid.rs:26:15 + --> $DIR/nested-type-ascription-syntactically-invalid.rs:25:15 | LL | let a @ (b: u8); | ^ expected one of `)`, `,`, `@`, or `|` error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `=`, found `)` - --> $DIR/nested-type-ascription-syntactically-invalid.rs:26:19 + --> $DIR/nested-type-ascription-syntactically-invalid.rs:25:19 | LL | let a @ (b: u8); | ^ expected one of 7 possible tokens error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `=`, found `@` - --> $DIR/nested-type-ascription-syntactically-invalid.rs:33:15 + --> $DIR/nested-type-ascription-syntactically-invalid.rs:32:15 | LL | let a: T1 @ Outer(b: T2); | ^ expected one of 7 possible tokens -warning: the feature `bindings_after_at` is incomplete and may cause the compiler to crash - --> $DIR/nested-type-ascription-syntactically-invalid.rs:4:12 - | -LL | #![feature(bindings_after_at)] - | ^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - error: aborting due to 4 previous errors diff --git a/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.rs b/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.rs index f0be901e3da7c..89ea2d5181945 100644 --- a/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.rs +++ b/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.rs @@ -2,7 +2,6 @@ // 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 diff --git a/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr b/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr index 34ae84c2a819b..c568d2a3aa2b8 100644 --- a/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr +++ b/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr @@ -1,76 +1,70 @@ error[E0415]: identifier `a` is bound more than once in this parameter list - --> $DIR/pat-at-same-name-both.rs:10:14 + --> $DIR/pat-at-same-name-both.rs:9:14 | LL | fn f(a @ a @ a: ()) {} | ^ used as parameter more than once error[E0415]: identifier `a` is bound more than once in this parameter list - --> $DIR/pat-at-same-name-both.rs:10:18 + --> $DIR/pat-at-same-name-both.rs:9:18 | LL | fn f(a @ a @ a: ()) {} | ^ used as parameter more than once error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/pat-at-same-name-both.rs:15:20 + --> $DIR/pat-at-same-name-both.rs:14:20 | LL | Ok(a @ b @ 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:17:23 + --> $DIR/pat-at-same-name-both.rs:16:23 | LL | | Err(a @ b @ 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:22:13 + --> $DIR/pat-at-same-name-both.rs:21: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:22:17 + --> $DIR/pat-at-same-name-both.rs:21: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:25:21 + --> $DIR/pat-at-same-name-both.rs:24: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:27:29 + --> $DIR/pat-at-same-name-both.rs:26: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:30:17 + --> $DIR/pat-at-same-name-both.rs:29: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:30:26 + --> $DIR/pat-at-same-name-both.rs:29: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 + --> $DIR/pat-at-same-name-both.rs:5:12 | LL | #![feature(or_patterns)] | ^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default error: aborting due to 10 previous errors From acfe58272cb188e2da69d2bf1285bf2d954de9a2 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Dec 2019 08:06:56 +0100 Subject: [PATCH 17/17] adjust E0303 error code docs --- src/librustc_error_codes/error_codes/E0303.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/librustc_error_codes/error_codes/E0303.md b/src/librustc_error_codes/error_codes/E0303.md index 20a6c078f4fa2..700a66438e060 100644 --- a/src/librustc_error_codes/error_codes/E0303.md +++ b/src/librustc_error_codes/error_codes/E0303.md @@ -1,10 +1,18 @@ +#### Note: this error code is no longer emitted by the compiler. + +Sub-bindings, e.g. `ref x @ Some(ref y)` are now allowed under +`#![feature(bindings_after_at)]` and checked to make sure that +memory safety is upheld. + +-------------- + In certain cases it is possible for sub-bindings to violate memory safety. Updates to the borrow checker in a future version of Rust may remove this restriction, but for now patterns must be rewritten without sub-bindings. Before: -```compile_fail,E0303 +```compile_fail match Some("hi".to_string()) { ref op_string_ref @ Some(s) => {}, None => {},