Auto merge of #137517 - nnethercote:rm-NtPat-NtItem-NtStmt, r=petrochenkov
Remove `NtPat`, `NtMeta`, and `NtPath` Another part of #124141. r? `@petrochenkov`
This commit is contained in:
commit
aa3c2d73ef
35 changed files with 189 additions and 236 deletions
|
@ -1024,7 +1024,7 @@ pub(crate) struct SuffixedLiteralInAttribute {
|
|||
pub(crate) struct InvalidMetaItem {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub token: Token,
|
||||
pub descr: String,
|
||||
#[subdiagnostic]
|
||||
pub quote_ident_sugg: Option<InvalidMetaItemQuoteIdentSugg>,
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
use rustc_ast::{self as ast, Attribute, attr, token};
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::token::{self, MetaVarKind};
|
||||
use rustc_ast::{Attribute, attr};
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{Diag, PResult};
|
||||
use rustc_span::{BytePos, Span};
|
||||
|
@ -9,7 +11,7 @@ use super::{
|
|||
AttrWrapper, Capturing, FnParseMode, ForceCollect, Parser, ParserRange, PathStyle, Trailing,
|
||||
UsePreAttrPos,
|
||||
};
|
||||
use crate::{errors, exp, fluent_generated as fluent, maybe_whole};
|
||||
use crate::{errors, exp, fluent_generated as fluent};
|
||||
|
||||
// Public for rustfmt usage
|
||||
#[derive(Debug)]
|
||||
|
@ -269,7 +271,12 @@ impl<'a> Parser<'a> {
|
|||
/// PATH `=` UNSUFFIXED_LIT
|
||||
/// The delimiters or `=` are still put into the resulting token stream.
|
||||
pub fn parse_attr_item(&mut self, force_collect: ForceCollect) -> PResult<'a, ast::AttrItem> {
|
||||
maybe_whole!(self, NtMeta, |attr| attr.into_inner());
|
||||
if let Some(item) = self.eat_metavar_seq_with_matcher(
|
||||
|mv_kind| matches!(mv_kind, MetaVarKind::Meta { .. }),
|
||||
|this| this.parse_attr_item(force_collect),
|
||||
) {
|
||||
return Ok(item);
|
||||
}
|
||||
|
||||
// Attr items don't have attributes.
|
||||
self.collect_tokens(None, AttrWrapper::empty(), force_collect, |this, _empty_attrs| {
|
||||
|
@ -396,18 +403,17 @@ impl<'a> Parser<'a> {
|
|||
&mut self,
|
||||
unsafe_allowed: AllowLeadingUnsafe,
|
||||
) -> PResult<'a, ast::MetaItem> {
|
||||
// We can't use `maybe_whole` here because it would bump in the `None`
|
||||
// case, which we don't want.
|
||||
if let token::Interpolated(nt) = &self.token.kind
|
||||
&& let token::NtMeta(attr_item) = &**nt
|
||||
{
|
||||
match attr_item.meta(attr_item.path.span) {
|
||||
Some(meta) => {
|
||||
self.bump();
|
||||
return Ok(meta);
|
||||
}
|
||||
None => self.unexpected()?,
|
||||
}
|
||||
if let Some(MetaVarKind::Meta { has_meta_form }) = self.token.is_metavar_seq() {
|
||||
return if has_meta_form {
|
||||
let attr_item = self
|
||||
.eat_metavar_seq(MetaVarKind::Meta { has_meta_form: true }, |this| {
|
||||
this.parse_attr_item(ForceCollect::No)
|
||||
})
|
||||
.unwrap();
|
||||
Ok(attr_item.meta(attr_item.path.span).unwrap())
|
||||
} else {
|
||||
self.unexpected_any()
|
||||
};
|
||||
}
|
||||
|
||||
let lo = self.token.span;
|
||||
|
@ -464,7 +470,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
let mut err = errors::InvalidMetaItem {
|
||||
span: self.token.span,
|
||||
token: self.token.clone(),
|
||||
descr: super::token_descr(&self.token),
|
||||
quote_ident_sugg: None,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
use std::mem::take;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::sync::Arc;
|
||||
|
||||
use ast::token::IdentIsRaw;
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{self, Delimiter, Lit, LitKind, Token, TokenKind};
|
||||
use rustc_ast::tokenstream::AttrTokenTree;
|
||||
use rustc_ast::util::parser::AssocOp;
|
||||
use rustc_ast::{
|
||||
AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingMode, Block,
|
||||
BlockCheckMode, Expr, ExprKind, GenericArg, Generics, HasTokens, Item, ItemKind, Param, Pat,
|
||||
PatKind, Path, PathSegment, QSelf, Recovered, Ty, TyKind,
|
||||
BlockCheckMode, Expr, ExprKind, GenericArg, Generics, Item, ItemKind, Param, Pat, PatKind,
|
||||
Path, PathSegment, QSelf, Recovered, Ty, TyKind,
|
||||
};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
|
@ -2406,52 +2404,6 @@ impl<'a> Parser<'a> {
|
|||
err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
|
||||
}
|
||||
err.span_label(span, "expected expression");
|
||||
|
||||
// Walk the chain of macro expansions for the current token to point at how the original
|
||||
// code was interpreted. This helps the user realize when a macro argument of one type is
|
||||
// later reinterpreted as a different type, like `$x:expr` being reinterpreted as `$x:pat`
|
||||
// in a subsequent macro invocation (#71039).
|
||||
let mut tok = self.token.clone();
|
||||
let mut labels = vec![];
|
||||
while let TokenKind::Interpolated(nt) = &tok.kind {
|
||||
let tokens = nt.tokens();
|
||||
labels.push(Arc::clone(nt));
|
||||
if let Some(tokens) = tokens
|
||||
&& let tokens = tokens.to_attr_token_stream()
|
||||
&& let tokens = tokens.0.deref()
|
||||
&& let [AttrTokenTree::Token(token, _)] = &tokens[..]
|
||||
{
|
||||
tok = token.clone();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
let mut iter = labels.into_iter().peekable();
|
||||
let mut show_link = false;
|
||||
while let Some(nt) = iter.next() {
|
||||
let descr = nt.descr();
|
||||
if let Some(next) = iter.peek() {
|
||||
let next_descr = next.descr();
|
||||
if next_descr != descr {
|
||||
err.span_label(next.use_span(), format!("this is expected to be {next_descr}"));
|
||||
err.span_label(
|
||||
nt.use_span(),
|
||||
format!(
|
||||
"this is interpreted as {}, but it is expected to be {}",
|
||||
next_descr, descr,
|
||||
),
|
||||
);
|
||||
show_link = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if show_link {
|
||||
err.note(
|
||||
"when forwarding a matched fragment to another macro-by-example, matchers in the \
|
||||
second macro will see an opaque AST of the fragment type, not the underlying \
|
||||
tokens",
|
||||
);
|
||||
}
|
||||
err
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use core::mem;
|
|||
use core::ops::{Bound, ControlFlow};
|
||||
|
||||
use ast::mut_visit::{self, MutVisitor};
|
||||
use ast::token::IdentIsRaw;
|
||||
use ast::token::{IdentIsRaw, MetaVarKind};
|
||||
use ast::{CoroutineKind, ForLoopKind, GenBlockKind, MatchKind, Pat, Path, PathSegment, Recovered};
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
|
||||
|
@ -1344,6 +1344,7 @@ impl<'a> Parser<'a> {
|
|||
fn parse_expr_bottom(&mut self) -> PResult<'a, P<Expr>> {
|
||||
maybe_recover_from_interpolated_ty_qpath!(self, true);
|
||||
|
||||
let span = self.token.span;
|
||||
if let token::Interpolated(nt) = &self.token.kind {
|
||||
match &**nt {
|
||||
token::NtExpr(e) | token::NtLiteral(e) => {
|
||||
|
@ -1351,11 +1352,6 @@ impl<'a> Parser<'a> {
|
|||
self.bump();
|
||||
return Ok(e);
|
||||
}
|
||||
token::NtPath(path) => {
|
||||
let path = (**path).clone();
|
||||
self.bump();
|
||||
return Ok(self.mk_expr(self.prev_token.span, ExprKind::Path(None, path)));
|
||||
}
|
||||
token::NtBlock(block) => {
|
||||
let block = block.clone();
|
||||
self.bump();
|
||||
|
@ -1363,6 +1359,10 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
_ => {}
|
||||
};
|
||||
} else if let Some(path) = self.eat_metavar_seq(MetaVarKind::Path, |this| {
|
||||
this.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))
|
||||
}) {
|
||||
return Ok(self.mk_expr(span, ExprKind::Path(None, path)));
|
||||
}
|
||||
|
||||
// Outer attributes are already parsed and will be
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::mem;
|
|||
use ast::token::IdentIsRaw;
|
||||
use rustc_ast::ast::*;
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{self, Delimiter, TokenKind};
|
||||
use rustc_ast::token::{self, Delimiter, InvisibleOrigin, MetaVarKind, TokenKind};
|
||||
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
|
||||
use rustc_ast::util::case::Case;
|
||||
use rustc_ast::{self as ast};
|
||||
|
@ -3071,8 +3071,10 @@ impl<'a> Parser<'a> {
|
|||
|
||||
fn is_named_param(&self) -> bool {
|
||||
let offset = match &self.token.kind {
|
||||
token::Interpolated(nt) => match &**nt {
|
||||
token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon),
|
||||
token::OpenDelim(Delimiter::Invisible(origin)) => match origin {
|
||||
InvisibleOrigin::MetaVar(MetaVarKind::Pat(_)) => {
|
||||
return self.check_noexpect_past_close_delim(&token::Colon);
|
||||
}
|
||||
_ => 0,
|
||||
},
|
||||
token::BinOp(token::And) | token::AndAnd => 1,
|
||||
|
|
|
@ -24,7 +24,8 @@ pub use pat::{CommaRecoveryMode, RecoverColon, RecoverComma};
|
|||
use path::PathStyle;
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{
|
||||
self, Delimiter, IdentIsRaw, InvisibleOrigin, MetaVarKind, Nonterminal, Token, TokenKind,
|
||||
self, Delimiter, IdentIsRaw, InvisibleOrigin, MetaVarKind, Nonterminal, NtPatKind, Token,
|
||||
TokenKind,
|
||||
};
|
||||
use rustc_ast::tokenstream::{AttrsTarget, Spacing, TokenStream, TokenTree};
|
||||
use rustc_ast::util::case::Case;
|
||||
|
@ -1745,7 +1746,10 @@ pub enum ParseNtResult {
|
|||
Tt(TokenTree),
|
||||
Ident(Ident, IdentIsRaw),
|
||||
Lifetime(Ident, IdentIsRaw),
|
||||
Pat(P<ast::Pat>, NtPatKind),
|
||||
Ty(P<ast::Ty>),
|
||||
Meta(P<ast::AttrItem>),
|
||||
Path(P<ast::Path>),
|
||||
Vis(P<ast::Visibility>),
|
||||
|
||||
/// This variant will eventually be removed, along with `Token::Interpolate`.
|
||||
|
|
|
@ -32,7 +32,7 @@ impl<'a> Parser<'a> {
|
|||
| MetaVarKind::Expr { .. }
|
||||
| MetaVarKind::Ty { .. }
|
||||
| MetaVarKind::Literal // `true`, `false`
|
||||
| MetaVarKind::Meta
|
||||
| MetaVarKind::Meta { .. }
|
||||
| MetaVarKind::Path => true,
|
||||
|
||||
MetaVarKind::Item
|
||||
|
@ -49,11 +49,9 @@ impl<'a> Parser<'a> {
|
|||
fn nt_may_be_ident(nt: &Nonterminal) -> bool {
|
||||
match nt {
|
||||
NtStmt(_)
|
||||
| NtPat(_)
|
||||
| NtExpr(_)
|
||||
| NtLiteral(_) // `true`, `false`
|
||||
| NtMeta(_)
|
||||
| NtPath(_) => true,
|
||||
=> true,
|
||||
|
||||
NtItem(_) | NtBlock(_) => false,
|
||||
}
|
||||
|
@ -99,7 +97,7 @@ impl<'a> Parser<'a> {
|
|||
token::NtLifetime(..) => true,
|
||||
token::Interpolated(nt) => match &**nt {
|
||||
NtBlock(_) | NtStmt(_) | NtExpr(_) | NtLiteral(_) => true,
|
||||
NtItem(_) | NtPat(_) | NtMeta(_) | NtPath(_) => false,
|
||||
NtItem(_) => false,
|
||||
},
|
||||
token::OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(k))) => match k {
|
||||
MetaVarKind::Block
|
||||
|
@ -109,7 +107,7 @@ impl<'a> Parser<'a> {
|
|||
MetaVarKind::Item
|
||||
| MetaVarKind::Pat(_)
|
||||
| MetaVarKind::Ty { .. }
|
||||
| MetaVarKind::Meta
|
||||
| MetaVarKind::Meta { .. }
|
||||
| MetaVarKind::Path
|
||||
| MetaVarKind::Vis => false,
|
||||
MetaVarKind::Lifetime | MetaVarKind::Ident | MetaVarKind::TT => {
|
||||
|
@ -170,15 +168,18 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
},
|
||||
NonterminalKind::Pat(pat_kind) => {
|
||||
NtPat(self.collect_tokens_no_attrs(|this| match pat_kind {
|
||||
PatParam { .. } => this.parse_pat_no_top_alt(None, None),
|
||||
PatWithOr => this.parse_pat_no_top_guard(
|
||||
None,
|
||||
RecoverComma::No,
|
||||
RecoverColon::No,
|
||||
CommaRecoveryMode::EitherTupleOrPipe,
|
||||
),
|
||||
})?)
|
||||
return Ok(ParseNtResult::Pat(
|
||||
self.collect_tokens_no_attrs(|this| match pat_kind {
|
||||
PatParam { .. } => this.parse_pat_no_top_alt(None, None),
|
||||
PatWithOr => this.parse_pat_no_top_guard(
|
||||
None,
|
||||
RecoverComma::No,
|
||||
RecoverColon::No,
|
||||
CommaRecoveryMode::EitherTupleOrPipe,
|
||||
),
|
||||
})?,
|
||||
pat_kind,
|
||||
));
|
||||
}
|
||||
NonterminalKind::Expr(_) => NtExpr(self.parse_expr_force_collect()?),
|
||||
NonterminalKind::Literal => {
|
||||
|
@ -203,9 +204,13 @@ impl<'a> Parser<'a> {
|
|||
};
|
||||
}
|
||||
NonterminalKind::Path => {
|
||||
NtPath(P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?))
|
||||
return Ok(ParseNtResult::Path(P(
|
||||
self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?
|
||||
)));
|
||||
}
|
||||
NonterminalKind::Meta => {
|
||||
return Ok(ParseNtResult::Meta(P(self.parse_attr_item(ForceCollect::Yes)?)));
|
||||
}
|
||||
NonterminalKind::Meta => NtMeta(P(self.parse_attr_item(ForceCollect::Yes)?)),
|
||||
NonterminalKind::Vis => {
|
||||
return Ok(ParseNtResult::Vis(P(self.collect_tokens_no_attrs(|this| {
|
||||
this.parse_visibility(FollowedByType::Yes)
|
||||
|
|
|
@ -2,7 +2,8 @@ use std::ops::Bound;
|
|||
|
||||
use rustc_ast::mut_visit::{self, MutVisitor};
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token};
|
||||
use rustc_ast::token::NtPatKind::*;
|
||||
use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, MetaVarKind, Token};
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_ast::visit::{self, Visitor};
|
||||
use rustc_ast::{
|
||||
|
@ -30,7 +31,7 @@ use crate::errors::{
|
|||
UnexpectedVertVertInPattern, WrapInParens,
|
||||
};
|
||||
use crate::parser::expr::{DestructuredFloat, could_be_unclosed_char_literal};
|
||||
use crate::{exp, maybe_recover_from_interpolated_ty_qpath, maybe_whole};
|
||||
use crate::{exp, maybe_recover_from_interpolated_ty_qpath};
|
||||
|
||||
#[derive(PartialEq, Copy, Clone)]
|
||||
pub enum Expected {
|
||||
|
@ -689,6 +690,27 @@ impl<'a> Parser<'a> {
|
|||
PatVisitor { parser: self, stmt, arm: None, field: None }.visit_stmt(stmt);
|
||||
}
|
||||
|
||||
fn eat_metavar_pat(&mut self) -> Option<P<Pat>> {
|
||||
// Must try both kinds of pattern nonterminals.
|
||||
if let Some(pat) = self.eat_metavar_seq_with_matcher(
|
||||
|mv_kind| matches!(mv_kind, MetaVarKind::Pat(PatParam { .. })),
|
||||
|this| this.parse_pat_no_top_alt(None, None),
|
||||
) {
|
||||
Some(pat)
|
||||
} else if let Some(pat) = self.eat_metavar_seq(MetaVarKind::Pat(PatWithOr), |this| {
|
||||
this.parse_pat_no_top_guard(
|
||||
None,
|
||||
RecoverComma::No,
|
||||
RecoverColon::No,
|
||||
CommaRecoveryMode::EitherTupleOrPipe,
|
||||
)
|
||||
}) {
|
||||
Some(pat)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses a pattern, with a setting whether modern range patterns (e.g., `a..=b`, `a..b` are
|
||||
/// allowed).
|
||||
fn parse_pat_with_range_pat(
|
||||
|
@ -698,7 +720,10 @@ impl<'a> Parser<'a> {
|
|||
syntax_loc: Option<PatternLocation>,
|
||||
) -> PResult<'a, P<Pat>> {
|
||||
maybe_recover_from_interpolated_ty_qpath!(self, true);
|
||||
maybe_whole!(self, NtPat, |pat| pat);
|
||||
|
||||
if let Some(pat) = self.eat_metavar_pat() {
|
||||
return Ok(pat);
|
||||
}
|
||||
|
||||
let mut lo = self.token.span;
|
||||
|
||||
|
@ -1043,10 +1068,8 @@ impl<'a> Parser<'a> {
|
|||
self.recover_additional_muts();
|
||||
|
||||
// Make sure we don't allow e.g. `let mut $p;` where `$p:pat`.
|
||||
if let token::Interpolated(nt) = &self.token.kind {
|
||||
if let token::NtPat(..) = &**nt {
|
||||
self.expected_ident_found_err().emit();
|
||||
}
|
||||
if let Some(MetaVarKind::Pat(_)) = self.token.is_metavar_seq() {
|
||||
self.expected_ident_found_err().emit();
|
||||
}
|
||||
|
||||
// Parse the pattern we hope to be an identifier.
|
||||
|
|
|
@ -15,9 +15,9 @@ use tracing::debug;
|
|||
|
||||
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
|
||||
use super::{Parser, Restrictions, TokenType};
|
||||
use crate::errors::{PathSingleColon, PathTripleColon};
|
||||
use crate::errors::{self, PathSingleColon, PathTripleColon};
|
||||
use crate::exp;
|
||||
use crate::parser::{CommaRecoveryMode, RecoverColon, RecoverComma};
|
||||
use crate::{errors, exp, maybe_whole};
|
||||
|
||||
/// Specifies how to parse a path.
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
|
@ -194,7 +194,11 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
};
|
||||
|
||||
maybe_whole!(self, NtPath, |path| reject_generics_if_mod_style(self, path.into_inner()));
|
||||
if let Some(path) =
|
||||
self.eat_metavar_seq(MetaVarKind::Path, |this| this.parse_path(PathStyle::Type))
|
||||
{
|
||||
return Ok(reject_generics_if_mod_style(self, path));
|
||||
}
|
||||
|
||||
// If we have a `ty` metavar in the form of a path, reparse it directly as a path, instead
|
||||
// of reparsing it as a `ty` and then extracting the path.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue