Stabilize bind_by_move_pattern_guards in 1.39.0.
This commit is contained in:
parent
43a5ff4222
commit
961a4da08e
@ -5,11 +5,6 @@
|
||||
use super::{Pattern, PatternContext, PatternError, PatternKind};
|
||||
|
||||
use rustc::middle::borrowck::SignalledError;
|
||||
use rustc::middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor};
|
||||
use rustc::middle::expr_use_visitor::{LoanCause, MutateMode};
|
||||
use rustc::middle::expr_use_visitor as euv;
|
||||
use rustc::middle::mem_categorization::cmt_;
|
||||
use rustc::middle::region;
|
||||
use rustc::session::Session;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::subst::{InternalSubsts, SubstsRef};
|
||||
@ -36,9 +31,7 @@
|
||||
|
||||
let mut visitor = MatchVisitor {
|
||||
tcx,
|
||||
body_owner: def_id,
|
||||
tables: tcx.body_tables(body_id),
|
||||
region_scope_tree: &tcx.region_scope_tree(def_id),
|
||||
param_env: tcx.param_env(def_id),
|
||||
identity_substs: InternalSubsts::identity_for_item(tcx, def_id),
|
||||
signalled_error: SignalledError::NoErrorsSeen,
|
||||
@ -53,11 +46,9 @@ fn create_e0004(sess: &Session, sp: Span, error_message: String) -> DiagnosticBu
|
||||
|
||||
struct MatchVisitor<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body_owner: DefId,
|
||||
tables: &'a ty::TypeckTables<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
identity_substs: SubstsRef<'tcx>,
|
||||
region_scope_tree: &'a region::ScopeTree,
|
||||
signalled_error: SignalledError,
|
||||
}
|
||||
|
||||
@ -151,11 +142,8 @@ fn check_match(
|
||||
|
||||
// Second, if there is a guard on each arm, make sure it isn't
|
||||
// assigning or borrowing anything mutably.
|
||||
if let Some(ref guard) = arm.guard {
|
||||
if arm.guard.is_some() {
|
||||
self.signalled_error = SignalledError::SawSomeError;
|
||||
if !self.tcx.features().bind_by_move_pattern_guards {
|
||||
check_for_mutation_in_guard(self, &guard);
|
||||
}
|
||||
}
|
||||
|
||||
// Third, perform some lints.
|
||||
@ -582,19 +570,10 @@ fn check_legality_of_move_bindings(
|
||||
"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 {
|
||||
if !cx.tcx.features().bind_by_move_pattern_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() {
|
||||
err.help("add `#![feature(bind_by_move_pattern_guards)]` to the \
|
||||
crate attributes to enable");
|
||||
}
|
||||
err.emit();
|
||||
} else if !has_guard {
|
||||
if let Some(_by_ref_span) = by_ref_span {
|
||||
span_vec.push(p.span);
|
||||
}
|
||||
} else if let Some(_by_ref_span) = by_ref_span {
|
||||
span_vec.push(p.span);
|
||||
}
|
||||
};
|
||||
|
||||
@ -636,67 +615,6 @@ fn check_legality_of_move_bindings(
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensures that a pattern guard doesn't borrow by mutable reference or assign.
|
||||
//
|
||||
// FIXME: this should be done by borrowck.
|
||||
fn check_for_mutation_in_guard(cx: &MatchVisitor<'_, '_>, guard: &hir::Guard) {
|
||||
let mut checker = MutationChecker {
|
||||
cx,
|
||||
};
|
||||
match guard {
|
||||
hir::Guard::If(expr) =>
|
||||
ExprUseVisitor::new(&mut checker,
|
||||
cx.tcx,
|
||||
cx.body_owner,
|
||||
cx.param_env,
|
||||
cx.region_scope_tree,
|
||||
cx.tables,
|
||||
None).walk_expr(expr),
|
||||
};
|
||||
}
|
||||
|
||||
struct MutationChecker<'a, 'tcx> {
|
||||
cx: &'a MatchVisitor<'a, 'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'tcx> {
|
||||
fn matched_pat(&mut self, _: &Pat, _: &cmt_<'_>, _: euv::MatchMode) {}
|
||||
fn consume(&mut self, _: hir::HirId, _: Span, _: &cmt_<'_>, _: ConsumeMode) {}
|
||||
fn consume_pat(&mut self, _: &Pat, _: &cmt_<'_>, _: ConsumeMode) {}
|
||||
fn borrow(&mut self,
|
||||
_: hir::HirId,
|
||||
span: Span,
|
||||
_: &cmt_<'_>,
|
||||
_: ty::Region<'tcx>,
|
||||
kind:ty:: BorrowKind,
|
||||
_: LoanCause) {
|
||||
match kind {
|
||||
ty::MutBorrow => {
|
||||
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() {
|
||||
err.help("add `#![feature(bind_by_move_pattern_guards)]` to the \
|
||||
crate attributes to enable");
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
ty::ImmBorrow | ty::UniqueImmBorrow => {}
|
||||
}
|
||||
}
|
||||
fn decl_without_init(&mut self, _: hir::HirId, _: Span) {}
|
||||
fn mutate(&mut self, _: hir::HirId, span: Span, _: &cmt_<'_>, mode: MutateMode) {
|
||||
match mode {
|
||||
MutateMode::JustWrite | MutateMode::WriteAndRead => {
|
||||
struct_span_err!(self.cx.tcx.sess, span, E0302, "cannot assign in a pattern guard")
|
||||
.span_label(span, "assignment in pattern guard")
|
||||
.emit();
|
||||
}
|
||||
MutateMode::Init => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Forbids bindings in `@` patterns. This is necessary for memory safety,
|
||||
/// because of the way rvalues are handled in the borrow check. (See issue
|
||||
/// #14587.)
|
||||
|
@ -241,6 +241,8 @@ macro_rules! declare_features {
|
||||
(accepted, underscore_const_names, "1.37.0", Some(54912), None),
|
||||
/// Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions.
|
||||
(accepted, async_await, "1.39.0", Some(50547), None),
|
||||
/// Allows mixing bind-by-move in patterns and references to those identifiers in guards.
|
||||
(accepted, bind_by_move_pattern_guards, "1.39.0", Some(15287), None),
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// feature-group-end: accepted features
|
||||
|
@ -461,9 +461,6 @@ pub fn set(&self, features: &mut Features, span: Span) {
|
||||
/// Allows non-builtin attributes in inner attribute position.
|
||||
(active, custom_inner_attributes, "1.30.0", Some(54726), None),
|
||||
|
||||
/// Allows mixing bind-by-move in patterns and references to those identifiers in guards.
|
||||
(active, bind_by_move_pattern_guards, "1.30.0", Some(15287), None),
|
||||
|
||||
/// Allows `impl Trait` in bindings (`let`, `const`, `static`).
|
||||
(active, impl_trait_in_bindings, "1.30.0", Some(63065), None),
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user