From 7d844e871c2b6d3c86adff53792fc36fdd338eb2 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 7 Sep 2018 17:52:27 +0200 Subject: [PATCH 1/3] Add `feature(bind_by_move_pattern_guards)`. Note it requires MIR-borrowck to be enabled to actually do anything. Note also that it implicitly turns off our AST-based check for mutation in guards. --- src/librustc/ty/context.rs | 29 +++++++++++++++++++- src/librustc_mir/hair/pattern/check_match.rs | 2 +- src/libsyntax/feature_gate.rs | 6 ++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 6738267b5b8c8..43bd82118c661 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1436,10 +1436,37 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.queries.on_disk_cache.serialize(self.global_tcx(), encoder) } + /// This checks whether one is allowed to have pattern bindings + /// that bind-by-move on a match arm that has a guard, e.g.: + /// + /// ```rust + /// match foo { A(inner) if { /* something */ } => ..., ... } + /// ``` + /// + /// It is separate from check_for_mutation_in_guard_via_ast_walk, + /// because that method has a narrower effect that can be toggled + /// off via a separate `-Z` flag, at least for the short term. + pub fn allow_bind_by_move_patterns_with_guards(self) -> bool { + self.features().bind_by_move_pattern_guards && self.use_mir_borrowck() + } + /// If true, we should use a naive AST walk to determine if match /// guard could perform bad mutations (or mutable-borrows). pub fn check_for_mutation_in_guard_via_ast_walk(self) -> bool { - !self.sess.opts.debugging_opts.disable_ast_check_for_mutation_in_guard + // If someone passes the `-Z` flag, they're asking for the footgun. + if self.sess.opts.debugging_opts.disable_ast_check_for_mutation_in_guard { + return false; + } + + // If someone requests the feature, then be a little more + // careful and ensure that MIR-borrowck is enabled (which can + // happen via edition selection, via `feature(nll)`, or via an + // appropriate `-Z` flag) before disabling the mutation check. + if self.allow_bind_by_move_patterns_with_guards() { + return false; + } + + return true; } /// If true, we should use the AST-based borrowck (we may *also* use diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index bf878145e1fb9..507019559fc30 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -537,7 +537,7 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, "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 { + } else if has_guard && !cx.tcx.allow_bind_by_move_patterns_with_guards() { struct_span_err!(cx.tcx.sess, p.span, E0008, "cannot bind by-move into a pattern guard") .span_label(p.span, "moves value into pattern guard") diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 7266d807d3ba8..922e773f1443b 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -515,6 +515,12 @@ declare_features! ( // Self struct constructor (RFC 2302) (active, self_struct_ctor, "1.31.0", Some(51994), None), + + // allow mixing of bind-by-move in patterns and references to + // those identifiers in guards, *if* we are using MIR-borrowck + // (aka NLL). Essentially this means you need to be on + // edition:2018 or later. + (active, bind_by_move_pattern_guards, "1.30.0", Some(15287), None), ); declare_features! ( From c50884c6157645d22d8fb1ee1beb2c1552d570c7 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 7 Sep 2018 17:52:49 +0200 Subject: [PATCH 2/3] Tests for `feature(bind_by_move_pattern_guards)`. Apparently copyright notices are no longer necessary apparently. (See #43498 and #53654.) --- .../ui/bind-by-move/bind-by-move-no-guards.rs | 10 ---- .../bind-by-move-no-guards.stderr | 2 +- .../bind-by-move-no-guards.rs | 21 +++++++++ .../feature-gate.gate_and_2015.stderr | 9 ++++ .../feature-gate.gate_and_2018.stderr | 10 ++++ .../feature-gate.gate_and_feature_nll.stderr | 10 ++++ .../feature-gate.gate_and_znll.stderr | 10 ++++ .../feature-gate.no_gate.stderr | 9 ++++ .../feature-gate.rs | 47 +++++++++++++++++++ .../rfc-basic-examples.rs | 40 ++++++++++++++++ .../rfc-reject-double-move-across-arms.rs | 16 +++++++ .../rfc-reject-double-move-across-arms.stderr | 9 ++++ .../rfc-reject-double-move-in-first-arm.rs | 17 +++++++ ...rfc-reject-double-move-in-first-arm.stderr | 9 ++++ 14 files changed, 208 insertions(+), 11 deletions(-) create mode 100644 src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs create mode 100644 src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2015.stderr create mode 100644 src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2018.stderr create mode 100644 src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_feature_nll.stderr create mode 100644 src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_znll.stderr create mode 100644 src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.no_gate.stderr create mode 100644 src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.rs create mode 100644 src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs create mode 100644 src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs create mode 100644 src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr create mode 100644 src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs create mode 100644 src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr diff --git a/src/test/ui/bind-by-move/bind-by-move-no-guards.rs b/src/test/ui/bind-by-move/bind-by-move-no-guards.rs index bb6060f2543e2..bc9b3a8de4ef5 100644 --- a/src/test/ui/bind-by-move/bind-by-move-no-guards.rs +++ b/src/test/ui/bind-by-move/bind-by-move-no-guards.rs @@ -1,13 +1,3 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use std::sync::mpsc::channel; fn main() { diff --git a/src/test/ui/bind-by-move/bind-by-move-no-guards.stderr b/src/test/ui/bind-by-move/bind-by-move-no-guards.stderr index ed516cd559ebb..2af2b0d660efa 100644 --- a/src/test/ui/bind-by-move/bind-by-move-no-guards.stderr +++ b/src/test/ui/bind-by-move/bind-by-move-no-guards.stderr @@ -1,5 +1,5 @@ error[E0008]: cannot bind by-move into a pattern guard - --> $DIR/bind-by-move-no-guards.rs:18:14 + --> $DIR/bind-by-move-no-guards.rs:8:14 | LL | Some(z) if z.recv().unwrap() => { panic!() }, | ^ moves value into pattern guard diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs new file mode 100644 index 0000000000000..2f3c094ff3954 --- /dev/null +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs @@ -0,0 +1,21 @@ +// Adaptation of existing ui test (from way back in +// rust-lang/rust#2329), that starts passing with this feature in +// place. + +// compile-pass + +#![feature(nll)] +#![feature(bind_by_move_pattern_guards)] + +use std::sync::mpsc::channel; + +fn main() { + let (tx, rx) = channel(); + let x = Some(rx); + tx.send(false); + match x { + Some(z) if z.recv().unwrap() => { panic!() }, + Some(z) => { assert!(!z.recv().unwrap()); }, + None => panic!() + } +} diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2015.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2015.stderr new file mode 100644 index 0000000000000..4c17ce23b3768 --- /dev/null +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2015.stderr @@ -0,0 +1,9 @@ +error[E0008]: cannot bind by-move into a pattern guard + --> $DIR/feature-gate.rs:33:16 + | +LL | A { a: v } if *v == 42 => v, + | ^ moves value into pattern guard + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0008`. diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2018.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2018.stderr new file mode 100644 index 0000000000000..4bde9b0c8d910 --- /dev/null +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2018.stderr @@ -0,0 +1,10 @@ +error: compilation successful + --> $DIR/feature-gate.rs:42:1 + | +LL | / fn main() { +LL | | foo(107) +LL | | } + | |_^ + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_feature_nll.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_feature_nll.stderr new file mode 100644 index 0000000000000..4bde9b0c8d910 --- /dev/null +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_feature_nll.stderr @@ -0,0 +1,10 @@ +error: compilation successful + --> $DIR/feature-gate.rs:42:1 + | +LL | / fn main() { +LL | | foo(107) +LL | | } + | |_^ + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_znll.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_znll.stderr new file mode 100644 index 0000000000000..4bde9b0c8d910 --- /dev/null +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_znll.stderr @@ -0,0 +1,10 @@ +error: compilation successful + --> $DIR/feature-gate.rs:42:1 + | +LL | / fn main() { +LL | | foo(107) +LL | | } + | |_^ + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.no_gate.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.no_gate.stderr new file mode 100644 index 0000000000000..4c17ce23b3768 --- /dev/null +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.no_gate.stderr @@ -0,0 +1,9 @@ +error[E0008]: cannot bind by-move into a pattern guard + --> $DIR/feature-gate.rs:33:16 + | +LL | A { a: v } if *v == 42 => v, + | ^ moves value into pattern guard + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0008`. diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.rs new file mode 100644 index 0000000000000..f6df4d07baad0 --- /dev/null +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.rs @@ -0,0 +1,47 @@ +// Check that pattern-guards with move-bound variables is only allowed +// with the appropriate set of feature gates. (Note that we require +// the code to opt into MIR-borrowck in *some* way before the feature +// will work; we use the revision system here to enumerate a number of +// ways that opt-in could occur.) + +// gate-test-bind_by_move_pattern_guards + +// revisions: no_gate gate_and_2015 gate_and_2018 gate_and_znll gate_and_feature_nll + +// (We're already testing NLL behavior quite explicitly, no need for compare-mode=nll.) +// ignore-compare-mode-nll + +#![feature(rustc_attrs)] + +#![cfg_attr(gate_and_2015, feature(bind_by_move_pattern_guards))] +#![cfg_attr(gate_and_2018, feature(bind_by_move_pattern_guards))] +#![cfg_attr(gate_and_znll, feature(bind_by_move_pattern_guards))] +#![cfg_attr(gate_and_feature_nll, feature(bind_by_move_pattern_guards))] + +#![cfg_attr(gate_and_feature_nll, feature(nll))] + +//[gate_and_2015] edition:2015 +//[gate_and_2018] edition:2018 +//[gate_and_znll] compile-flags: -Z borrowck=mir + +struct A { a: Box } + +fn foo(n: i32) { + let x = A { a: Box::new(n) }; + let _y = match x { + + A { a: v } if *v == 42 => v, + //[no_gate]~^ ERROR cannot bind by-move into a pattern guard + //[gate_and_2015]~^^ ERROR cannot bind by-move into a pattern guard + + _ => Box::new(0) + }; +} + +#[rustc_error] +fn main() { + foo(107) +} +//[gate_and_2018]~^^^ ERROR compilation successful +//[gate_and_znll]~^^^^ ERROR compilation successful +//[gate_and_feature_nll]~^^^^^ ERROR compilation successful diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs new file mode 100644 index 0000000000000..9a9d11ce1b13e --- /dev/null +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs @@ -0,0 +1,40 @@ +#![feature(nll)] +#![feature(bind_by_move_pattern_guards)] + +// compile-pass + +struct A { a: Box } + +impl A { + fn get(&self) -> i32 { *self.a } +} + +fn foo(n: i32) { + let x = A { a: Box::new(n) }; + let y = match x { + A { a: v } if *v == 42 => v, + _ => Box::new(0), + }; +} + +fn bar(n: i32) { + let x = A { a: Box::new(n) }; + let y = match x { + A { a: v } if x.get() == 42 => v, + _ => Box::new(0), + }; +} + +fn baz(n: i32) { + let x = A { a: Box::new(n) }; + let y = match x { + A { a: v } if *v.clone() == 42 => v, + _ => Box::new(0), + }; +} + +fn main() { + foo(107); + bar(107); + baz(107); +} diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs new file mode 100644 index 0000000000000..0fec6b273d3bc --- /dev/null +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs @@ -0,0 +1,16 @@ +#![feature(nll)] +#![feature(bind_by_move_pattern_guards)] + +enum VecWrapper { A(Vec) } + +fn foo(x: VecWrapper) -> usize { + match x { + VecWrapper::A(v) if { drop(v); false } => 1, + //~^ ERROR cannot move out of borrowed content + VecWrapper::A(v) => v.len() + } +} + +fn main() { + foo(VecWrapper::A(vec![107])); +} diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr new file mode 100644 index 0000000000000..502006e1b3f90 --- /dev/null +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr @@ -0,0 +1,9 @@ +error[E0507]: cannot move out of borrowed content + --> $DIR/rfc-reject-double-move-across-arms.rs:8:36 + | +LL | VecWrapper::A(v) if { drop(v); false } => 1, + | ^ cannot move out of borrowed content + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs new file mode 100644 index 0000000000000..396bfc1c93199 --- /dev/null +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs @@ -0,0 +1,17 @@ +#![feature(nll)] +#![feature(bind_by_move_pattern_guards)] + +struct A { a: Box } + +fn foo(n: i32) { + let x = A { a: Box::new(n) }; + let _y = match x { + A { a: v } if { drop(v); true } => v, + //~^ ERROR cannot move out of borrowed content + _ => Box::new(0), + }; +} + +fn main() { + foo(107); +} diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr new file mode 100644 index 0000000000000..dd8f42f749709 --- /dev/null +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr @@ -0,0 +1,9 @@ +error[E0507]: cannot move out of borrowed content + --> $DIR/rfc-reject-double-move-in-first-arm.rs:9:30 + | +LL | A { a: v } if { drop(v); true } => v, + | ^ cannot move out of borrowed content + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0507`. From 3a07d3dbd6cdb2014369935b62b36c64d6c580a6 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Mon, 10 Sep 2018 11:47:28 +0200 Subject: [PATCH 3/3] On nightly with NLL, suggest `#![feature(bind_by_move_pattern_guards)]` when it might fix the code. --- src/librustc_mir/hair/pattern/check_match.rs | 26 +++++++++++++------ .../bind-by-move-no-guards.nll.stderr | 11 ++++++++ .../borrowck-mutate-in-guard.nll.stderr | 24 +++++++++++++++++ src/test/ui/error-codes/E0008.nll.stderr | 11 ++++++++ src/test/ui/error-codes/E0301.nll.stderr | 11 ++++++++ 5 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/bind-by-move/bind-by-move-no-guards.nll.stderr create mode 100644 src/test/ui/borrowck/borrowck-mutate-in-guard.nll.stderr create mode 100644 src/test/ui/error-codes/E0008.nll.stderr create mode 100644 src/test/ui/error-codes/E0301.nll.stderr diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 507019559fc30..23667d1b331a3 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -538,10 +538,14 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, .span_label(p.span, "binds an already bound by-move value by moving it") .emit(); } else if has_guard && !cx.tcx.allow_bind_by_move_patterns_with_guards() { - struct_span_err!(cx.tcx.sess, p.span, E0008, - "cannot bind by-move into a pattern guard") - .span_label(p.span, "moves value into pattern guard") - .emit(); + let mut err = struct_span_err!(cx.tcx.sess, p.span, E0008, + "cannot bind by-move into a pattern guard"); + err.span_label(p.span, "moves value into pattern guard"); + if cx.tcx.sess.opts.unstable_features.is_nightly_build() && cx.tcx.use_mir_borrowck() { + err.help("add #![feature(bind_by_move_pattern_guards)] to the \ + crate attributes to enable"); + } + err.emit(); } else if let Some(by_ref_span) = by_ref_span { struct_span_err!( cx.tcx.sess, @@ -613,10 +617,16 @@ impl<'a, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'tcx> { _: LoanCause) { match kind { ty::MutBorrow => { - struct_span_err!(self.cx.tcx.sess, span, E0301, - "cannot mutably borrow in a pattern guard") - .span_label(span, "borrowed mutably in pattern guard") - .emit(); + let mut err = struct_span_err!(self.cx.tcx.sess, span, E0301, + "cannot mutably borrow in a pattern guard"); + err.span_label(span, "borrowed mutably in pattern guard"); + if self.cx.tcx.sess.opts.unstable_features.is_nightly_build() && + self.cx.tcx.use_mir_borrowck() + { + err.help("add #![feature(bind_by_move_pattern_guards)] to the \ + crate attributes to enable"); + } + err.emit(); } ty::ImmBorrow | ty::UniqueImmBorrow => {} } diff --git a/src/test/ui/bind-by-move/bind-by-move-no-guards.nll.stderr b/src/test/ui/bind-by-move/bind-by-move-no-guards.nll.stderr new file mode 100644 index 0000000000000..5f8b7007f304c --- /dev/null +++ b/src/test/ui/bind-by-move/bind-by-move-no-guards.nll.stderr @@ -0,0 +1,11 @@ +error[E0008]: cannot bind by-move into a pattern guard + --> $DIR/bind-by-move-no-guards.rs:8:14 + | +LL | Some(z) if z.recv().unwrap() => { panic!() }, + | ^ moves value into pattern guard + | + = help: add #![feature(bind_by_move_pattern_guards)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0008`. diff --git a/src/test/ui/borrowck/borrowck-mutate-in-guard.nll.stderr b/src/test/ui/borrowck/borrowck-mutate-in-guard.nll.stderr new file mode 100644 index 0000000000000..b363a78cbc206 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-mutate-in-guard.nll.stderr @@ -0,0 +1,24 @@ +error[E0302]: cannot assign in a pattern guard + --> $DIR/borrowck-mutate-in-guard.rs:20:25 + | +LL | Enum::A(_) if { x = Enum::B(false); false } => 1, + | ^^^^^^^^^^^^^^^^^^ assignment in pattern guard + +error[E0301]: cannot mutably borrow in a pattern guard + --> $DIR/borrowck-mutate-in-guard.rs:22:38 + | +LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1, + | ^ borrowed mutably in pattern guard + | + = help: add #![feature(bind_by_move_pattern_guards)] to the crate attributes to enable + +error[E0302]: cannot assign in a pattern guard + --> $DIR/borrowck-mutate-in-guard.rs:22:41 + | +LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1, + | ^^^^^^^^^^^^^^^^^^^ assignment in pattern guard + +error: aborting due to 3 previous errors + +Some errors occurred: E0301, E0302. +For more information about an error, try `rustc --explain E0301`. diff --git a/src/test/ui/error-codes/E0008.nll.stderr b/src/test/ui/error-codes/E0008.nll.stderr new file mode 100644 index 0000000000000..ce627cb741a37 --- /dev/null +++ b/src/test/ui/error-codes/E0008.nll.stderr @@ -0,0 +1,11 @@ +error[E0008]: cannot bind by-move into a pattern guard + --> $DIR/E0008.rs:13:14 + | +LL | Some(s) if s.len() == 0 => {}, + | ^ moves value into pattern guard + | + = help: add #![feature(bind_by_move_pattern_guards)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0008`. diff --git a/src/test/ui/error-codes/E0301.nll.stderr b/src/test/ui/error-codes/E0301.nll.stderr new file mode 100644 index 0000000000000..f060eb9043535 --- /dev/null +++ b/src/test/ui/error-codes/E0301.nll.stderr @@ -0,0 +1,11 @@ +error[E0301]: cannot mutably borrow in a pattern guard + --> $DIR/E0301.rs:14:19 + | +LL | option if option.take().is_none() => {}, //~ ERROR E0301 + | ^^^^^^ borrowed mutably in pattern guard + | + = help: add #![feature(bind_by_move_pattern_guards)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0301`.