Remove NtPath.

This commit is contained in:
Nicholas Nethercote 2024-04-18 20:09:37 +10:00
parent 7ea59e053b
commit 50076cdeb9
15 changed files with 48 additions and 73 deletions

View file

@ -202,7 +202,6 @@ impl HasTokens for Nonterminal {
Nonterminal::NtItem(item) => item.tokens(), Nonterminal::NtItem(item) => item.tokens(),
Nonterminal::NtStmt(stmt) => stmt.tokens(), Nonterminal::NtStmt(stmt) => stmt.tokens(),
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens(), Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens(),
Nonterminal::NtPath(path) => path.tokens(),
Nonterminal::NtBlock(block) => block.tokens(), Nonterminal::NtBlock(block) => block.tokens(),
} }
} }
@ -211,7 +210,6 @@ impl HasTokens for Nonterminal {
Nonterminal::NtItem(item) => item.tokens_mut(), Nonterminal::NtItem(item) => item.tokens_mut(),
Nonterminal::NtStmt(stmt) => stmt.tokens_mut(), Nonterminal::NtStmt(stmt) => stmt.tokens_mut(),
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens_mut(), Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens_mut(),
Nonterminal::NtPath(path) => path.tokens_mut(),
Nonterminal::NtBlock(block) => block.tokens_mut(), Nonterminal::NtBlock(block) => block.tokens_mut(),
} }
} }

View file

@ -405,14 +405,12 @@ impl MetaItem {
let span = span.with_hi(segments.last().unwrap().ident.span.hi()); let span = span.with_hi(segments.last().unwrap().ident.span.hi());
Path { span, segments, tokens: None } Path { span, segments, tokens: None }
} }
Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match &**nt {
token::Nonterminal::NtPath(path) => (**path).clone(),
_ => return None,
},
Some(TokenTree::Delimited( Some(TokenTree::Delimited(
_span, _span,
_spacing, _spacing,
Delimiter::Invisible(InvisibleOrigin::MetaVar(MetaVarKind::Meta { .. })), Delimiter::Invisible(InvisibleOrigin::MetaVar(
MetaVarKind::Meta { .. } | MetaVarKind::Path,
)),
_stream, _stream,
)) => { )) => {
// This path is currently unreachable in the test suite. // This path is currently unreachable in the test suite.

View file

@ -907,7 +907,6 @@ fn visit_nonterminal<T: MutVisitor>(vis: &mut T, nt: &mut token::Nonterminal) {
}), }),
token::NtExpr(expr) => vis.visit_expr(expr), token::NtExpr(expr) => vis.visit_expr(expr),
token::NtLiteral(expr) => vis.visit_expr(expr), token::NtLiteral(expr) => vis.visit_expr(expr),
token::NtPath(path) => vis.visit_path(path),
} }
} }

View file

@ -624,8 +624,7 @@ impl Token {
matches!(&**nt, matches!(&**nt,
NtBlock(..) | NtBlock(..) |
NtExpr(..) | NtExpr(..) |
NtLiteral(..) | NtLiteral(..)
NtPath(..)
), ),
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar( OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
MetaVarKind::Block | MetaVarKind::Block |
@ -661,7 +660,6 @@ impl Token {
matches!(&**nt, matches!(&**nt,
| NtExpr(..) | NtExpr(..)
| NtLiteral(..) | NtLiteral(..)
| NtPath(..)
), ),
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar( OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
MetaVarKind::Expr { .. } | MetaVarKind::Expr { .. } |
@ -690,7 +688,6 @@ impl Token {
Lifetime(..) | // lifetime bound in trait object Lifetime(..) | // lifetime bound in trait object
Lt | BinOp(Shl) | // associated path Lt | BinOp(Shl) | // associated path
PathSep => true, // global path PathSep => true, // global path
Interpolated(ref nt) => matches!(&**nt, NtPath(..)),
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar( OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
MetaVarKind::Ty { .. } | MetaVarKind::Ty { .. } |
MetaVarKind::Path MetaVarKind::Path
@ -849,27 +846,16 @@ impl Token {
self.ident().is_some_and(|(ident, _)| ident.name == name) self.ident().is_some_and(|(ident, _)| ident.name == name)
} }
/// Returns `true` if the token is an interpolated path.
fn is_whole_path(&self) -> bool {
if let Interpolated(nt) = &self.kind
&& let NtPath(..) = &**nt
{
return true;
}
false
}
/// Is this a pre-parsed expression dropped into the token stream /// Is this a pre-parsed expression dropped into the token stream
/// (which happens while parsing the result of macro expansion)? /// (which happens while parsing the result of macro expansion)?
pub fn is_whole_expr(&self) -> bool { pub fn is_whole_expr(&self) -> bool {
if let Interpolated(nt) = &self.kind if let Interpolated(nt) = &self.kind
&& let NtExpr(_) | NtLiteral(_) | NtPath(_) | NtBlock(_) = &**nt && let NtExpr(_) | NtLiteral(_) | NtBlock(_) = &**nt
{ {
return true; true
} else {
matches!(self.is_metavar_seq(), Some(MetaVarKind::Path))
} }
false
} }
/// Is the token an interpolated block (`$b:block`)? /// Is the token an interpolated block (`$b:block`)?
@ -895,7 +881,7 @@ impl Token {
pub fn is_path_start(&self) -> bool { pub fn is_path_start(&self) -> bool {
self == &PathSep self == &PathSep
|| self.is_qpath_start() || self.is_qpath_start()
|| self.is_whole_path() || matches!(self.is_metavar_seq(), Some(MetaVarKind::Path))
|| self.is_path_segment_keyword() || self.is_path_segment_keyword()
|| self.is_ident() && !self.is_reserved_ident() || self.is_ident() && !self.is_reserved_ident()
} }
@ -1078,7 +1064,6 @@ pub enum Nonterminal {
NtStmt(P<ast::Stmt>), NtStmt(P<ast::Stmt>),
NtExpr(P<ast::Expr>), NtExpr(P<ast::Expr>),
NtLiteral(P<ast::Expr>), NtLiteral(P<ast::Expr>),
NtPath(P<ast::Path>),
} }
#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, HashStable_Generic)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, HashStable_Generic)]
@ -1171,7 +1156,6 @@ impl Nonterminal {
NtBlock(block) => block.span, NtBlock(block) => block.span,
NtStmt(stmt) => stmt.span, NtStmt(stmt) => stmt.span,
NtExpr(expr) | NtLiteral(expr) => expr.span, NtExpr(expr) | NtLiteral(expr) => expr.span,
NtPath(path) => path.span,
} }
} }
@ -1182,7 +1166,6 @@ impl Nonterminal {
NtStmt(..) => "statement", NtStmt(..) => "statement",
NtExpr(..) => "expression", NtExpr(..) => "expression",
NtLiteral(..) => "literal", NtLiteral(..) => "literal",
NtPath(..) => "path",
} }
} }
} }
@ -1205,7 +1188,6 @@ impl fmt::Debug for Nonterminal {
NtStmt(..) => f.pad("NtStmt(..)"), NtStmt(..) => f.pad("NtStmt(..)"),
NtExpr(..) => f.pad("NtExpr(..)"), NtExpr(..) => f.pad("NtExpr(..)"),
NtLiteral(..) => f.pad("NtLiteral(..)"), NtLiteral(..) => f.pad("NtLiteral(..)"),
NtPath(..) => f.pad("NtPath(..)"),
} }
} }
} }

View file

@ -468,7 +468,6 @@ impl TokenStream {
TokenStream::token_alone(token::Semi, stmt.span) TokenStream::token_alone(token::Semi, stmt.span)
} }
Nonterminal::NtStmt(stmt) => TokenStream::from_ast(stmt), Nonterminal::NtStmt(stmt) => TokenStream::from_ast(stmt),
Nonterminal::NtPath(path) => TokenStream::from_ast(path),
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => TokenStream::from_ast(expr), Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => TokenStream::from_ast(expr),
} }
} }

View file

@ -477,32 +477,21 @@ impl<'a> MetaItemListParserContext<'a> {
// or a path. // or a path.
let path = let path =
if let Some(TokenTree::Token(Token { kind: token::Interpolated(nt), span, .. }, _)) = if let Some(TokenTree::Token(Token { kind: token::Interpolated(_), span, .. }, _)) =
self.inside_delimiters.peek() self.inside_delimiters.peek()
{ {
match &**nt { self.inside_delimiters.next();
// an already interpolated path from a macro expansion is a path, no need to parse // We go into this path if an expr ended up in an attribute that
// one from tokens // expansion did not turn into a literal. Say, `#[repr(align(macro!()))]`
token::Nonterminal::NtPath(path) => { // where the macro didn't expand to a literal. An error is already given
self.inside_delimiters.next(); // for this at this point, and then we do continue. This makes this path
// reachable...
let e = self.dcx.span_delayed_bug(
*span,
"expr in place where literal is expected (builtin attr parsing)",
);
AttrPath::from_ast(path) return Some(MetaItemOrLitParser::Err(*span, e));
}
_ => {
self.inside_delimiters.next();
// we go into this path if an expr ended up in an attribute that
// expansion did not turn into a literal. Say, `#[repr(align(macro!()))]`
// where the macro didn't expand to a literal. An error is already given
// for this at this point, and then we do continue. This makes this path
// reachable...
let e = self.dcx.span_delayed_bug(
*span,
"expr in place where literal is expected (builtin attr parsing)",
);
return Some(MetaItemOrLitParser::Err(*span, e));
}
}
} else { } else {
self.next_path()? self.next_path()?
}; };

View file

@ -344,6 +344,9 @@ pub(super) fn transcribe<'a>(
TokenStream::from_ast(attr_item), TokenStream::from_ast(attr_item),
) )
} }
MatchedSingle(ParseNtResult::Path(path)) => {
mk_delimited(path.span, MetaVarKind::Path, TokenStream::from_ast(path))
}
MatchedSingle(ParseNtResult::Vis(vis)) => { MatchedSingle(ParseNtResult::Vis(vis)) => {
mk_delimited(vis.span, MetaVarKind::Vis, TokenStream::from_ast(vis)) mk_delimited(vis.span, MetaVarKind::Vis, TokenStream::from_ast(vis))
} }

View file

@ -4,7 +4,7 @@ use core::mem;
use core::ops::{Bound, ControlFlow}; use core::ops::{Bound, ControlFlow};
use ast::mut_visit::{self, MutVisitor}; 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 ast::{CoroutineKind, ForLoopKind, GenBlockKind, MatchKind, Pat, Path, PathSegment, Recovered};
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter, Token, TokenKind}; use rustc_ast::token::{self, Delimiter, Token, TokenKind};
@ -1382,6 +1382,7 @@ impl<'a> Parser<'a> {
fn parse_expr_bottom(&mut self) -> PResult<'a, P<Expr>> { fn parse_expr_bottom(&mut self) -> PResult<'a, P<Expr>> {
maybe_recover_from_interpolated_ty_qpath!(self, true); maybe_recover_from_interpolated_ty_qpath!(self, true);
let span = self.token.span;
if let token::Interpolated(nt) = &self.token.kind { if let token::Interpolated(nt) = &self.token.kind {
match &**nt { match &**nt {
token::NtExpr(e) | token::NtLiteral(e) => { token::NtExpr(e) | token::NtLiteral(e) => {
@ -1389,11 +1390,6 @@ impl<'a> Parser<'a> {
self.bump(); self.bump();
return Ok(e); 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) => { token::NtBlock(block) => {
let block = block.clone(); let block = block.clone();
self.bump(); self.bump();
@ -1401,6 +1397,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 // Outer attributes are already parsed and will be

View file

@ -1749,6 +1749,7 @@ pub enum ParseNtResult {
Pat(P<ast::Pat>, NtPatKind), Pat(P<ast::Pat>, NtPatKind),
Ty(P<ast::Ty>), Ty(P<ast::Ty>),
Meta(P<ast::AttrItem>), Meta(P<ast::AttrItem>),
Path(P<ast::Path>),
Vis(P<ast::Visibility>), Vis(P<ast::Visibility>),
/// This variant will eventually be removed, along with `Token::Interpolate`. /// This variant will eventually be removed, along with `Token::Interpolate`.

View file

@ -51,7 +51,7 @@ impl<'a> Parser<'a> {
NtStmt(_) NtStmt(_)
| NtExpr(_) | NtExpr(_)
| NtLiteral(_) // `true`, `false` | NtLiteral(_) // `true`, `false`
| NtPath(_) => true, => true,
NtItem(_) | NtBlock(_) => false, NtItem(_) | NtBlock(_) => false,
} }
@ -97,7 +97,7 @@ impl<'a> Parser<'a> {
token::NtLifetime(..) => true, token::NtLifetime(..) => true,
token::Interpolated(nt) => match &**nt { token::Interpolated(nt) => match &**nt {
NtBlock(_) | NtStmt(_) | NtExpr(_) | NtLiteral(_) => true, NtBlock(_) | NtStmt(_) | NtExpr(_) | NtLiteral(_) => true,
NtItem(_) | NtPath(_) => false, NtItem(_) => false,
}, },
token::OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(k))) => match k { token::OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(k))) => match k {
MetaVarKind::Block MetaVarKind::Block
@ -204,7 +204,9 @@ impl<'a> Parser<'a> {
}; };
} }
NonterminalKind::Path => { 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 => { NonterminalKind::Meta => {
return Ok(ParseNtResult::Meta(P(self.parse_attr_item(ForceCollect::Yes)?))); return Ok(ParseNtResult::Meta(P(self.parse_attr_item(ForceCollect::Yes)?)));

View file

@ -15,9 +15,9 @@ use tracing::debug;
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
use super::{Parser, Restrictions, TokenType}; 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::parser::{CommaRecoveryMode, RecoverColon, RecoverComma};
use crate::{errors, exp, maybe_whole};
/// Specifies how to parse a path. /// Specifies how to parse a path.
#[derive(Copy, Clone, PartialEq)] #[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 // 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. // of reparsing it as a `ty` and then extracting the path.

View file

@ -8,7 +8,7 @@ mod a {
} }
macro_rules! import { macro_rules! import {
($p: path) => (use ::$p {S, Z}); //~ERROR expected identifier, found `a::b::c` ($p: path) => (use ::$p {S, Z}); //~ERROR expected identifier, found metavariable
} }
import! { a::b::c } import! { a::b::c }

View file

@ -1,8 +1,8 @@
error: expected identifier, found `a::b::c` error: expected identifier, found metavariable
--> $DIR/import-prefix-macro-2.rs:11:26 --> $DIR/import-prefix-macro-2.rs:11:26
| |
LL | ($p: path) => (use ::$p {S, Z}); LL | ($p: path) => (use ::$p {S, Z});
| ^^ expected identifier | ^^ expected identifier, found metavariable
... ...
LL | import! { a::b::c } LL | import! { a::b::c }
| ------------------- in this macro invocation | ------------------- in this macro invocation

View file

@ -31,7 +31,7 @@ macro_rules! foo {
(tt $x:tt) => { bar!(tt $x); }; (tt $x:tt) => { bar!(tt $x); };
(expr $x:expr) => { bar!(expr $x); }; //~ ERROR: no rules expected expression `3` (expr $x:expr) => { bar!(expr $x); }; //~ ERROR: no rules expected expression `3`
(literal $x:literal) => { bar!(literal $x); }; //~ ERROR: no rules expected literal `4` (literal $x:literal) => { bar!(literal $x); }; //~ ERROR: no rules expected literal `4`
(path $x:path) => { bar!(path $x); }; //~ ERROR: no rules expected path `a::b::c` (path $x:path) => { bar!(path $x); }; //~ ERROR: no rules expected `path` metavariable
(stmt $x:stmt) => { bar!(stmt $x); }; //~ ERROR: no rules expected statement `let abc = 0` (stmt $x:stmt) => { bar!(stmt $x); }; //~ ERROR: no rules expected statement `let abc = 0`
} }

View file

@ -67,7 +67,7 @@ LL | (literal 4) => {};
= help: try using `:tt` instead in the macro definition = help: try using `:tt` instead in the macro definition
= note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
error: no rules expected path `a::b::c` error: no rules expected `path` metavariable
--> $DIR/nonterminal-matching.rs:34:35 --> $DIR/nonterminal-matching.rs:34:35
| |
LL | (path $x:path) => { bar!(path $x); }; LL | (path $x:path) => { bar!(path $x); };