Remove NtPath
.
This commit is contained in:
parent
7ea59e053b
commit
50076cdeb9
15 changed files with 48 additions and 73 deletions
|
@ -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(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(..)"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()?
|
||||||
};
|
};
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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`.
|
||||||
|
|
|
@ -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)?)));
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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); };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue