diff options
| author | Felix S. Klock II <pnkfelix@pnkfx.org> | 2018-09-07 17:52:27 +0200 |
|---|---|---|
| committer | Felix S. Klock II <pnkfelix@pnkfx.org> | 2018-09-17 13:46:50 +0200 |
| commit | 7d844e871c2b6d3c86adff53792fc36fdd338eb2 (patch) | |
| tree | b0a1c602705c20ee6689f2c4a6051e1666ccfcea | |
| parent | f1aefb48d2ec7ac38a66c964396a5aec729b7a28 (diff) | |
| download | rust-7d844e871c2b6d3c86adff53792fc36fdd338eb2.tar.gz rust-7d844e871c2b6d3c86adff53792fc36fdd338eb2.zip | |
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.
| -rw-r--r-- | src/librustc/ty/context.rs | 29 | ||||
| -rw-r--r-- | src/librustc_mir/hair/pattern/check_match.rs | 2 | ||||
| -rw-r--r-- | 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 6738267b5b8..43bd82118c6 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 bf878145e1f..507019559fc 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 7266d807d3b..922e773f144 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! ( |
