]> git.lizzy.rs Git - rust.git/commitdiff
Add `feature(bind_by_move_pattern_guards)`.
authorFelix S. Klock II <pnkfelix@pnkfx.org>
Fri, 7 Sep 2018 15:52:27 +0000 (17:52 +0200)
committerFelix S. Klock II <pnkfelix@pnkfx.org>
Mon, 17 Sep 2018 11:46:50 +0000 (13:46 +0200)
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
src/librustc_mir/hair/pattern/check_match.rs
src/libsyntax/feature_gate.rs

index 6738267b5b8c809ef5f987b39d88c0ddce10bc6f..43bd82118c6617269ed5c7fb6e99d828ddc892a8 100644 (file)
@@ -1436,10 +1436,37 @@ pub fn serialize_query_result_cache<E>(self,
         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
index bf878145e1fb972ba906caa194f7928044db9e65..507019559fc304999121e79e4ae836824fb4c707 100644 (file)
@@ -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")
index 7266d807d3ba8644fa60ea4b4c5810f417b4f92d..922e773f1443b196a23eee4a4628e227421972ef 100644 (file)
@@ -515,6 +515,12 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
 
     // 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! (