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
This commit is contained in:
commit
e19cb40fda
10 changed files with 106 additions and 73 deletions
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue