about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/ty/context.rs29
-rw-r--r--src/librustc_mir/hair/pattern/check_match.rs28
-rw-r--r--src/libsyntax/feature_gate.rs6
-rw-r--r--src/test/ui/bind-by-move/bind-by-move-no-guards.nll.stderr11
-rw-r--r--src/test/ui/bind-by-move/bind-by-move-no-guards.rs10
-rw-r--r--src/test/ui/bind-by-move/bind-by-move-no-guards.stderr2
-rw-r--r--src/test/ui/borrowck/borrowck-mutate-in-guard.nll.stderr24
-rw-r--r--src/test/ui/error-codes/E0008.nll.stderr11
-rw-r--r--src/test/ui/error-codes/E0301.nll.stderr11
-rw-r--r--src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs21
-rw-r--r--src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2015.stderr9
-rw-r--r--src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2018.stderr10
-rw-r--r--src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_feature_nll.stderr10
-rw-r--r--src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_znll.stderr10
-rw-r--r--src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.no_gate.stderr9
-rw-r--r--src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.rs47
-rw-r--r--src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs40
-rw-r--r--src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs16
-rw-r--r--src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr9
-rw-r--r--src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs17
-rw-r--r--src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr9
21 files changed, 318 insertions, 21 deletions
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 03c0b680acf..b7b0fdca2e6 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -1448,10 +1448,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 bf878145e1f..23667d1b331 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -537,11 +537,15 @@ 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 {
-            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();
+        } else if has_guard && !cx.tcx.allow_bind_by_move_patterns_with_guards() {
+            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/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 67a9601fb12..8ddb7473162 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! (
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 00000000000..5f8b7007f30
--- /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/bind-by-move/bind-by-move-no-guards.rs b/src/test/ui/bind-by-move/bind-by-move-no-guards.rs
index bb6060f2543..bc9b3a8de4e 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 ed516cd559e..2af2b0d660e 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/borrowck/borrowck-mutate-in-guard.nll.stderr b/src/test/ui/borrowck/borrowck-mutate-in-guard.nll.stderr
new file mode 100644
index 00000000000..b363a78cbc2
--- /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 00000000000..ce627cb741a
--- /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 00000000000..f060eb90435
--- /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`.
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 00000000000..2f3c094ff39
--- /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 00000000000..4c17ce23b37
--- /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 00000000000..4bde9b0c8d9
--- /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 00000000000..4bde9b0c8d9
--- /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 00000000000..4bde9b0c8d9
--- /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 00000000000..4c17ce23b37
--- /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 00000000000..f6df4d07baa
--- /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<i32> }
+
+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 00000000000..9a9d11ce1b1
--- /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<i32> }
+
+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 00000000000..0fec6b273d3
--- /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<i32>) }
+
+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 00000000000..502006e1b3f
--- /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 00000000000..396bfc1c931
--- /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<i32> }
+
+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 00000000000..dd8f42f7497
--- /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`.