From 365d1236890469cff1a55a28eeb9befaf516d552 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 18 Sep 2019 10:27:31 -0700 Subject: [PATCH] Add feature gate for const `if` and `match` --- src/librustc_mir/transform/check_consts/ops.rs | 4 ++++ src/librustc_mir/transform/qualify_min_const_fn.rs | 13 +++++++++++-- src/librustc_passes/check_const.rs | 2 +- src/libsyntax/feature_gate/active.rs | 3 +++ src/libsyntax_pos/symbol.rs | 1 + 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/transform/check_consts/ops.rs b/src/librustc_mir/transform/check_consts/ops.rs index 80f2925193a..950f48f03cd 100644 --- a/src/librustc_mir/transform/check_consts/ops.rs +++ b/src/librustc_mir/transform/check_consts/ops.rs @@ -139,6 +139,10 @@ fn emit_error(&self, item: &Item<'_, '_>, span: Span) { #[derive(Debug)] pub struct IfOrMatch; impl NonConstOp for IfOrMatch { + fn feature_gate(tcx: TyCtxt<'_>) -> Option { + Some(tcx.features().const_if_match) + } + fn emit_error(&self, item: &Item<'_, '_>, span: Span) { // This should be caught by the HIR const-checker. item.tcx.sess.delay_span_bug( diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 83bde5ed34e..cb6f94adbf0 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -216,7 +216,9 @@ fn check_statement( check_rvalue(tcx, body, def_id, rval, span) } - StatementKind::FakeRead(FakeReadCause::ForMatchedPlace, _) => { + | StatementKind::FakeRead(FakeReadCause::ForMatchedPlace, _) + if !tcx.features().const_if_match + => { Err((span, "loops and conditional expressions are not stable in const fn".into())) } @@ -324,10 +326,17 @@ fn check_terminator( check_operand(tcx, value, span, def_id, body) }, - TerminatorKind::FalseEdges { .. } | TerminatorKind::SwitchInt { .. } => Err(( + | TerminatorKind::FalseEdges { .. } + | TerminatorKind::SwitchInt { .. } + if !tcx.features().const_if_match + => Err(( span, "loops and conditional expressions are not stable in const fn".into(), )), + | TerminatorKind::FalseEdges { .. } + | TerminatorKind::SwitchInt { .. } + => Ok(()), + | TerminatorKind::Abort | TerminatorKind::Unreachable => { Err((span, "const fn with unreachable code is not stable".into())) } diff --git a/src/librustc_passes/check_const.rs b/src/librustc_passes/check_const.rs index 9d37b4bdb76..9870a78bd44 100644 --- a/src/librustc_passes/check_const.rs +++ b/src/librustc_passes/check_const.rs @@ -135,7 +135,7 @@ fn visit_expr(&mut self, e: &'tcx hir::Expr) { self.const_check_violated(source.name(), e.span); } - hir::ExprKind::Match(_, _, source) => { + hir::ExprKind::Match(_, _, source) if !self.tcx.features().const_if_match => { use hir::MatchSource::*; let op = match source { diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs index bd029514a95..fa0ab90c702 100644 --- a/src/libsyntax/feature_gate/active.rs +++ b/src/libsyntax/feature_gate/active.rs @@ -529,6 +529,9 @@ pub fn set(&self, features: &mut Features, span: Span) { /// Allows using the `#[register_attr]` attribute. (active, register_tool, "1.41.0", Some(66079), None), + /// Allows the use of `if` and `match` in constants. + (active, const_if_match, "1.41.0", Some(49146), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 979074f17c7..e7238caca8e 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -202,6 +202,7 @@ const_fn, const_fn_union, const_generics, + const_if_match, const_indexing, const_in_array_repeat_expressions, const_let, -- 2.44.0