diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-11-07 08:51:57 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-11-07 08:51:57 +0100 |
| commit | e19cb40fda70ea3f75bc1927c114ea53d231b288 (patch) | |
| tree | cf0891bcc1fca581981d14c7ae6c550fc20f26da /src/libsyntax/parse | |
| parent | 883fe10da2f0651540fd5824898b7d7476969c41 (diff) | |
| parent | bceaba86b92325f807351426bfd93ba0513225a4 (diff) | |
| download | rust-e19cb40fda70ea3f75bc1927c114ea53d231b288.tar.gz rust-e19cb40fda70ea3f75bc1927c114ea53d231b288.zip | |
Rollup merge of #65974 - Centril:matcher-friendly-gating, r=petrochenkov
A scheme for more macro-matcher friendly pre-expansion gating
Pre-expansion gating will now avoid gating macro matchers that did not result in `Success(...)`. That is, the following is now OK despite `box 42` being a valid `expr` and that form being pre-expansion gated:
```rust
macro_rules! m {
($e:expr) => { 0 }; // This fails on the input below due to `, foo`.
(box $e:expr, foo) => { 1 }; // Successful matcher, we should get `2`.
}
fn main() {
assert_eq!(1, m!(box 42, foo));
}
```
Closes https://github.com/rust-lang/rust/issues/65846.
r? @petrochenkov
cc @Mark-Simulacrum
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser/expr.rs | 19 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser/generics.rs | 5 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser/item.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser/pat.rs | 16 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser/path.rs | 4 |
6 files changed, 24 insertions, 30 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 0c358b1caaf..1284e89f195 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1120,7 +1120,7 @@ impl<'a> Parser<'a> { self.expected_tokens.push(TokenType::Keyword(kw::Crate)); if self.is_crate_vis() { self.bump(); // `crate` - self.sess.gated_spans.crate_visibility_modifier.borrow_mut().push(self.prev_span); + self.sess.gated_spans.gate(sym::crate_visibility_modifier, self.prev_span); return Ok(respan(self.prev_span, VisibilityKind::Crate(CrateSugar::JustCrate))); } diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs index 80ea8f380fb..509e6482dcc 100644 --- a/src/libsyntax/parse/parser/expr.rs +++ b/src/libsyntax/parse/parser/expr.rs @@ -16,10 +16,10 @@ use crate::parse::token::{self, Token, TokenKind}; use crate::print::pprust; use crate::ptr::P; use crate::source_map::{self, Span}; -use crate::symbol::{kw, sym}; use crate::util::parser::{AssocOp, Fixity, prec_let_scrutinee_needs_par}; use errors::Applicability; +use syntax_pos::symbol::{kw, sym}; use syntax_pos::Symbol; use std::mem; use rustc_data_structures::thin_vec::ThinVec; @@ -252,7 +252,7 @@ impl<'a> Parser<'a> { self.last_type_ascription = Some((self.prev_span, maybe_path)); lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type)?; - self.sess.gated_spans.type_ascription.borrow_mut().push(lhs.span); + self.sess.gated_spans.gate(sym::type_ascription, lhs.span); continue } else if op == AssocOp::DotDot || op == AssocOp::DotDotEq { // If we didn’t have to handle `x..`/`x..=`, it would be pretty easy to @@ -455,7 +455,7 @@ impl<'a> Parser<'a> { let e = self.parse_prefix_expr(None); let (span, e) = self.interpolated_or_expr_span(e)?; let span = lo.to(span); - self.sess.gated_spans.box_syntax.borrow_mut().push(span); + self.sess.gated_spans.gate(sym::box_syntax, span); (span, ExprKind::Box(e)) } token::Ident(..) if self.token.is_ident_named(sym::not) => { @@ -1045,7 +1045,7 @@ impl<'a> Parser<'a> { } let span = lo.to(hi); - self.sess.gated_spans.yields.borrow_mut().push(span); + self.sess.gated_spans.gate(sym::generators, span); } else if self.eat_keyword(kw::Let) { return self.parse_let_expr(attrs); } else if is_span_rust_2018 && self.eat_keyword(kw::Await) { @@ -1268,7 +1268,7 @@ impl<'a> Parser<'a> { outer_attrs: ThinVec<Attribute>, ) -> PResult<'a, P<Expr>> { if let Some(label) = opt_label { - self.sess.gated_spans.label_break_value.borrow_mut().push(label.ident.span); + self.sess.gated_spans.gate(sym::label_break_value, label.ident.span); } self.expect(&token::OpenDelim(token::Brace))?; @@ -1297,7 +1297,7 @@ impl<'a> Parser<'a> { }; if asyncness.is_async() { // Feature-gate `async ||` closures. - self.sess.gated_spans.async_closure.borrow_mut().push(self.prev_span); + self.sess.gated_spans.gate(sym::async_closure, self.prev_span); } let capture_clause = self.parse_capture_clause(); @@ -1419,8 +1419,7 @@ impl<'a> Parser<'a> { if let ExprKind::Let(..) = cond.kind { // Remove the last feature gating of a `let` expression since it's stable. - let last = self.sess.gated_spans.let_chains.borrow_mut().pop(); - debug_assert_eq!(cond.span, last.unwrap()); + self.sess.gated_spans.ungate_last(sym::let_chains, cond.span); } Ok(cond) @@ -1437,7 +1436,7 @@ impl<'a> Parser<'a> { |this| this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into()) )?; let span = lo.to(expr.span); - self.sess.gated_spans.let_chains.borrow_mut().push(span); + self.sess.gated_spans.gate(sym::let_chains, span); Ok(self.mk_expr(span, ExprKind::Let(pat, expr), attrs)) } @@ -1658,7 +1657,7 @@ impl<'a> Parser<'a> { Err(error) } else { let span = span_lo.to(body.span); - self.sess.gated_spans.try_blocks.borrow_mut().push(span); + self.sess.gated_spans.gate(sym::try_blocks, span); Ok(self.mk_expr(span, ExprKind::TryBlock(body), attrs)) } } diff --git a/src/libsyntax/parse/parser/generics.rs b/src/libsyntax/parse/parser/generics.rs index 51caae69c86..3c094750b4d 100644 --- a/src/libsyntax/parse/parser/generics.rs +++ b/src/libsyntax/parse/parser/generics.rs @@ -3,7 +3,8 @@ use super::{Parser, PResult}; use crate::ast::{self, WhereClause, GenericParam, GenericParamKind, GenericBounds, Attribute}; use crate::parse::token; use crate::source_map::DUMMY_SP; -use crate::symbol::kw; + +use syntax_pos::symbol::{kw, sym}; impl<'a> Parser<'a> { /// Parses bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`. @@ -62,7 +63,7 @@ impl<'a> Parser<'a> { self.expect(&token::Colon)?; let ty = self.parse_ty()?; - self.sess.gated_spans.const_generics.borrow_mut().push(lo.to(self.prev_span)); + self.sess.gated_spans.gate(sym::const_generics, lo.to(self.prev_span)); Ok(GenericParam { ident, diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs index ebb1cf12996..9d543055f23 100644 --- a/src/libsyntax/parse/parser/item.rs +++ b/src/libsyntax/parse/parser/item.rs @@ -146,9 +146,7 @@ impl<'a> Parser<'a> { let unsafety = self.parse_unsafety(); if self.check_keyword(kw::Extern) { - self.sess.gated_spans.const_extern_fn.borrow_mut().push( - lo.to(self.token.span) - ); + self.sess.gated_spans.gate(sym::const_extern_fn, lo.to(self.token.span)); } let abi = self.parse_extern_abi()?; self.bump(); // `fn` @@ -831,7 +829,7 @@ impl<'a> Parser<'a> { .emit(); } - self.sess.gated_spans.trait_alias.borrow_mut().push(whole_span); + self.sess.gated_spans.gate(sym::trait_alias, whole_span); Ok((ident, ItemKind::TraitAlias(tps, bounds), None)) } else { @@ -1711,7 +1709,7 @@ impl<'a> Parser<'a> { let span = lo.to(self.prev_span); if !def.legacy { - self.sess.gated_spans.decl_macro.borrow_mut().push(span); + self.sess.gated_spans.gate(sym::decl_macro, span); } Ok(Some(self.mk_item(span, ident, ItemKind::MacroDef(def), vis.clone(), attrs.to_vec()))) diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs index 969d5dd8374..cc8738edff7 100644 --- a/src/libsyntax/parse/parser/pat.rs +++ b/src/libsyntax/parse/parser/pat.rs @@ -8,9 +8,8 @@ use crate::mut_visit::{noop_visit_pat, noop_visit_mac, MutVisitor}; use crate::parse::token::{self}; use crate::print::pprust; use crate::source_map::{respan, Span, Spanned}; -use crate::symbol::kw; use crate::ThinVec; - +use syntax_pos::symbol::{kw, sym}; use errors::{Applicability, DiagnosticBuilder}; type Expected = Option<&'static str>; @@ -52,11 +51,8 @@ impl<'a> Parser<'a> { // and no other gated or-pattern has been parsed thus far, // then we should really gate the leading `|`. // This complicated procedure is done purely for diagnostics UX. - if gated_leading_vert { - let mut or_pattern_spans = self.sess.gated_spans.or_patterns.borrow_mut(); - if or_pattern_spans.is_empty() { - or_pattern_spans.push(leading_vert_span); - } + if gated_leading_vert && self.sess.gated_spans.is_ungated(sym::or_patterns) { + self.sess.gated_spans.gate(sym::or_patterns, leading_vert_span); } Ok(pat) @@ -117,7 +113,7 @@ impl<'a> Parser<'a> { // Feature gate the or-pattern if instructed: if gate_or == GateOr::Yes { - self.sess.gated_spans.or_patterns.borrow_mut().push(or_pattern_span); + self.sess.gated_spans.gate(sym::or_patterns, or_pattern_span); } Ok(self.mk_pat(or_pattern_span, PatKind::Or(pats))) @@ -325,7 +321,7 @@ impl<'a> Parser<'a> { } else if self.eat_keyword(kw::Box) { // Parse `box pat` let pat = self.parse_pat_with_range_pat(false, None)?; - self.sess.gated_spans.box_patterns.borrow_mut().push(lo.to(self.prev_span)); + self.sess.gated_spans.gate(sym::box_patterns, lo.to(self.prev_span)); PatKind::Box(pat) } else if self.can_be_ident_pat() { // Parse `ident @ pat` @@ -612,7 +608,7 @@ impl<'a> Parser<'a> { } fn excluded_range_end(&self, span: Span) -> RangeEnd { - self.sess.gated_spans.exclusive_range_pattern.borrow_mut().push(span); + self.sess.gated_spans.gate(sym::exclusive_range_pattern, span); RangeEnd::Excluded } diff --git a/src/libsyntax/parse/parser/path.rs b/src/libsyntax/parse/parser/path.rs index f9944e36e2f..4438d61d9ee 100644 --- a/src/libsyntax/parse/parser/path.rs +++ b/src/libsyntax/parse/parser/path.rs @@ -5,7 +5,7 @@ use crate::ast::{self, QSelf, Path, PathSegment, Ident, ParenthesizedArgs, Angle use crate::ast::{AnonConst, GenericArg, AssocTyConstraint, AssocTyConstraintKind, BlockCheckMode}; use crate::parse::token::{self, Token}; use crate::source_map::{Span, BytePos}; -use crate::symbol::kw; +use syntax_pos::symbol::{kw, sym}; use std::mem; use log::debug; @@ -426,7 +426,7 @@ impl<'a> Parser<'a> { // Gate associated type bounds, e.g., `Iterator<Item: Ord>`. if let AssocTyConstraintKind::Bound { .. } = kind { - self.sess.gated_spans.associated_type_bounds.borrow_mut().push(span); + self.sess.gated_spans.gate(sym::associated_type_bounds, span); } constraints.push(AssocTyConstraint { |
