From ebea1c2cc0088353d92e65d34fcae2799b50a20f Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 11 May 2019 15:11:04 +0200 Subject: [PATCH] let_chains: Add feature gate. --- src/libsyntax/feature_gate.rs | 31 ++++++++++++++++++++++++++++++- src/libsyntax_pos/symbol.rs | 1 + 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 7f80e2099f6..1f64f1a6888 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -560,6 +560,9 @@ declare_features! ( // Allows calling constructor functions in `const fn`. (active, const_constructor, "1.37.0", Some(61456), None), + // Allows `if/while p && let q = r && ...` chains. + (active, let_chains, "1.37.0", Some(53667), None), + // #[repr(transparent)] on enums. (active, transparent_enums, "1.37.0", Some(60405), None), @@ -577,7 +580,8 @@ declare_features! ( const INCOMPLETE_FEATURES: &[Symbol] = &[ sym::impl_trait_in_bindings, sym::generic_associated_types, - sym::const_generics + sym::const_generics, + sym::let_chains, ]; declare_features! ( @@ -1936,6 +1940,27 @@ impl<'a> PostExpansionVisitor<'a> { Err(mut err) => err.emit(), } } + + /// Recurse into all places where a `let` expression would be feature gated + /// and emit gate post errors for those. + fn find_and_gate_lets(&mut self, e: &'a ast::Expr) { + match &e.node { + ast::ExprKind::Paren(e) => { + self.find_and_gate_lets(e); + } + ast::ExprKind::Binary(op, lhs, rhs) if op.node == ast::BinOpKind::And => { + self.find_and_gate_lets(lhs); + self.find_and_gate_lets(rhs); + } + ast::ExprKind::Let(..) => { + gate_feature_post!( + &self, let_chains, e.span, + "`let` expressions in this position are experimental" + ); + } + _ => {} + } + } } impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { @@ -2133,6 +2158,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_expr(&mut self, e: &'a ast::Expr) { match e.node { + ast::ExprKind::If(ref e, ..) | ast::ExprKind::While(ref e, ..) => match e.node { + ast::ExprKind::Let(..) => {} // Stable!, + _ => self.find_and_gate_lets(e), + } ast::ExprKind::Box(_) => { gate_feature_post!(&self, box_syntax, e.span, EXPLAIN_BOX_SYNTAX); } diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index c25e65eaddd..756bc8c29d8 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -354,6 +354,7 @@ symbols! { label_break_value, lang, lang_items, + let_chains, lhs, lib, lifetime,