Skip to content

Commit 7d844e8

Browse files
committed
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.
1 parent f1aefb4 commit 7d844e8

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

src/librustc/ty/context.rs

+28-1
Original file line numberDiff line numberDiff line change
@@ -1436,10 +1436,37 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
14361436
self.queries.on_disk_cache.serialize(self.global_tcx(), encoder)
14371437
}
14381438

1439+
/// This checks whether one is allowed to have pattern bindings
1440+
/// that bind-by-move on a match arm that has a guard, e.g.:
1441+
///
1442+
/// ```rust
1443+
/// match foo { A(inner) if { /* something */ } => ..., ... }
1444+
/// ```
1445+
///
1446+
/// It is separate from check_for_mutation_in_guard_via_ast_walk,
1447+
/// because that method has a narrower effect that can be toggled
1448+
/// off via a separate `-Z` flag, at least for the short term.
1449+
pub fn allow_bind_by_move_patterns_with_guards(self) -> bool {
1450+
self.features().bind_by_move_pattern_guards && self.use_mir_borrowck()
1451+
}
1452+
14391453
/// If true, we should use a naive AST walk to determine if match
14401454
/// guard could perform bad mutations (or mutable-borrows).
14411455
pub fn check_for_mutation_in_guard_via_ast_walk(self) -> bool {
1442-
!self.sess.opts.debugging_opts.disable_ast_check_for_mutation_in_guard
1456+
// If someone passes the `-Z` flag, they're asking for the footgun.
1457+
if self.sess.opts.debugging_opts.disable_ast_check_for_mutation_in_guard {
1458+
return false;
1459+
}
1460+
1461+
// If someone requests the feature, then be a little more
1462+
// careful and ensure that MIR-borrowck is enabled (which can
1463+
// happen via edition selection, via `feature(nll)`, or via an
1464+
// appropriate `-Z` flag) before disabling the mutation check.
1465+
if self.allow_bind_by_move_patterns_with_guards() {
1466+
return false;
1467+
}
1468+
1469+
return true;
14431470
}
14441471

14451472
/// If true, we should use the AST-based borrowck (we may *also* use

src/librustc_mir/hair/pattern/check_match.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor,
537537
"cannot bind by-move with sub-bindings")
538538
.span_label(p.span, "binds an already bound by-move value by moving it")
539539
.emit();
540-
} else if has_guard {
540+
} else if has_guard && !cx.tcx.allow_bind_by_move_patterns_with_guards() {
541541
struct_span_err!(cx.tcx.sess, p.span, E0008,
542542
"cannot bind by-move into a pattern guard")
543543
.span_label(p.span, "moves value into pattern guard")

src/libsyntax/feature_gate.rs

+6
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,12 @@ declare_features! (
515515

516516
// Self struct constructor (RFC 2302)
517517
(active, self_struct_ctor, "1.31.0", Some(51994), None),
518+
519+
// allow mixing of bind-by-move in patterns and references to
520+
// those identifiers in guards, *if* we are using MIR-borrowck
521+
// (aka NLL). Essentially this means you need to be on
522+
// edition:2018 or later.
523+
(active, bind_by_move_pattern_guards, "1.30.0", Some(15287), None),
518524
);
519525

520526
declare_features! (

0 commit comments

Comments
 (0)