Skip to content

Commit 06d28f4

Browse files
committed
Auto merge of #114292 - estebank:issue-71039, r=<try>
More detail when expecting expression but encountering bad macro argument Partially address #71039. ``` error: expected expression, found `1 + 1` --> $DIR/trace_faulty_macros.rs:49:37 | LL | (let $p:pat = $e:expr) => {test!(($p,$e))}; | -- this is interpreted as pattern `1 + 1` (in expansion #2) ... LL | (($p:pat, $e:pat)) => {let $p = $e;}; | ^^ expected expression ... LL | test!(let x = 1+1); | ------------------ | | | | | this is interpreted as expression `1 + 1` (in expansion #1) | in this macro invocation | = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) ```
2 parents d627cf0 + 24c4fa0 commit 06d28f4

28 files changed

+328
-160
lines changed

compiler/rustc_ast/src/ast_traits.rs

+18-18
Original file line numberDiff line numberDiff line change
@@ -231,29 +231,29 @@ impl HasTokens for Attribute {
231231
impl HasTokens for Nonterminal {
232232
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
233233
match self {
234-
Nonterminal::NtItem(item) => item.tokens(),
235-
Nonterminal::NtStmt(stmt) => stmt.tokens(),
236-
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens(),
237-
Nonterminal::NtPat(pat) => pat.tokens(),
238-
Nonterminal::NtTy(ty) => ty.tokens(),
239-
Nonterminal::NtMeta(attr_item) => attr_item.tokens(),
240-
Nonterminal::NtPath(path) => path.tokens(),
241-
Nonterminal::NtVis(vis) => vis.tokens(),
242-
Nonterminal::NtBlock(block) => block.tokens(),
234+
Nonterminal::NtItem(item, _) => item.tokens(),
235+
Nonterminal::NtStmt(stmt, _) => stmt.tokens(),
236+
Nonterminal::NtExpr(expr, _) | Nonterminal::NtLiteral(expr, _) => expr.tokens(),
237+
Nonterminal::NtPat(pat, _) => pat.tokens(),
238+
Nonterminal::NtTy(ty, _) => ty.tokens(),
239+
Nonterminal::NtMeta(attr_item, _) => attr_item.tokens(),
240+
Nonterminal::NtPath(path, _) => path.tokens(),
241+
Nonterminal::NtVis(vis, _) => vis.tokens(),
242+
Nonterminal::NtBlock(block, _) => block.tokens(),
243243
Nonterminal::NtIdent(..) | Nonterminal::NtLifetime(..) => None,
244244
}
245245
}
246246
fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
247247
match self {
248-
Nonterminal::NtItem(item) => item.tokens_mut(),
249-
Nonterminal::NtStmt(stmt) => stmt.tokens_mut(),
250-
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens_mut(),
251-
Nonterminal::NtPat(pat) => pat.tokens_mut(),
252-
Nonterminal::NtTy(ty) => ty.tokens_mut(),
253-
Nonterminal::NtMeta(attr_item) => attr_item.tokens_mut(),
254-
Nonterminal::NtPath(path) => path.tokens_mut(),
255-
Nonterminal::NtVis(vis) => vis.tokens_mut(),
256-
Nonterminal::NtBlock(block) => block.tokens_mut(),
248+
Nonterminal::NtItem(item, _) => item.tokens_mut(),
249+
Nonterminal::NtStmt(stmt, _) => stmt.tokens_mut(),
250+
Nonterminal::NtExpr(expr, _) | Nonterminal::NtLiteral(expr, _) => expr.tokens_mut(),
251+
Nonterminal::NtPat(pat, _) => pat.tokens_mut(),
252+
Nonterminal::NtTy(ty, _) => ty.tokens_mut(),
253+
Nonterminal::NtMeta(attr_item, _) => attr_item.tokens_mut(),
254+
Nonterminal::NtPath(path, _) => path.tokens_mut(),
255+
Nonterminal::NtVis(vis, _) => vis.tokens_mut(),
256+
Nonterminal::NtBlock(block, _) => block.tokens_mut(),
257257
Nonterminal::NtIdent(..) | Nonterminal::NtLifetime(..) => None,
258258
}
259259
}

compiler/rustc_ast/src/attr/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -343,8 +343,8 @@ impl MetaItem {
343343
Path { span, segments, tokens: None }
344344
}
345345
Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match &**nt {
346-
token::Nonterminal::NtMeta(item) => return item.meta(item.path.span),
347-
token::Nonterminal::NtPath(path) => (**path).clone(),
346+
token::Nonterminal::NtMeta(item, _) => return item.meta(item.path.span),
347+
token::Nonterminal::NtPath(path, _) => (**path).clone(),
348348
_ => return None,
349349
},
350350
_ => return None,

compiler/rustc_ast/src/mut_visit.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -793,33 +793,33 @@ pub fn visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) {
793793
// multiple items there....
794794
pub fn visit_nonterminal<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut T) {
795795
match nt {
796-
token::NtItem(item) => visit_clobber(item, |item| {
796+
token::NtItem(item, _) => visit_clobber(item, |item| {
797797
// This is probably okay, because the only visitors likely to
798798
// peek inside interpolated nodes will be renamings/markings,
799799
// which map single items to single items.
800800
vis.flat_map_item(item).expect_one("expected visitor to produce exactly one item")
801801
}),
802-
token::NtBlock(block) => vis.visit_block(block),
803-
token::NtStmt(stmt) => visit_clobber(stmt, |stmt| {
802+
token::NtBlock(block, _) => vis.visit_block(block),
803+
token::NtStmt(stmt, _) => visit_clobber(stmt, |stmt| {
804804
// See reasoning above.
805805
stmt.map(|stmt| {
806806
vis.flat_map_stmt(stmt).expect_one("expected visitor to produce exactly one item")
807807
})
808808
}),
809-
token::NtPat(pat) => vis.visit_pat(pat),
810-
token::NtExpr(expr) => vis.visit_expr(expr),
811-
token::NtTy(ty) => vis.visit_ty(ty),
812-
token::NtIdent(ident, _is_raw) => vis.visit_ident(ident),
813-
token::NtLifetime(ident) => vis.visit_ident(ident),
814-
token::NtLiteral(expr) => vis.visit_expr(expr),
815-
token::NtMeta(item) => {
809+
token::NtPat(pat, _) => vis.visit_pat(pat),
810+
token::NtExpr(expr, _) => vis.visit_expr(expr),
811+
token::NtTy(ty, _) => vis.visit_ty(ty),
812+
token::NtIdent(ident, _is_raw, _) => vis.visit_ident(ident),
813+
token::NtLifetime(ident, _) => vis.visit_ident(ident),
814+
token::NtLiteral(expr, _) => vis.visit_expr(expr),
815+
token::NtMeta(item, _) => {
816816
let AttrItem { path, args, tokens } = item.deref_mut();
817817
vis.visit_path(path);
818818
visit_attr_args(args, vis);
819819
visit_lazy_tts(tokens, vis);
820820
}
821-
token::NtPath(path) => vis.visit_path(path),
822-
token::NtVis(visib) => vis.visit_vis(visib),
821+
token::NtPath(path, _) => vis.visit_path(path),
822+
token::NtVis(visib, _) => vis.visit_vis(visib),
823823
}
824824
}
825825

compiler/rustc_ast/src/token.rs

+69-35
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ impl Lit {
112112
}
113113
Literal(token_lit) => Some(token_lit),
114114
Interpolated(ref nt)
115-
if let NtExpr(expr) | NtLiteral(expr) = &**nt
115+
if let NtExpr(expr, _) | NtLiteral(expr, _) = &**nt
116116
&& let ast::ExprKind::Lit(token_lit) = expr.kind =>
117117
{
118118
Some(token_lit)
@@ -395,7 +395,7 @@ impl Token {
395395
/// if they keep spans or perform edition checks.
396396
pub fn uninterpolated_span(&self) -> Span {
397397
match &self.kind {
398-
Interpolated(nt) => nt.span(),
398+
Interpolated(nt) => nt.use_span(),
399399
_ => self.span,
400400
}
401401
}
@@ -551,8 +551,8 @@ impl Token {
551551
Literal(..) | BinOp(Minus) => true,
552552
Ident(name, false) if name.is_bool_lit() => true,
553553
Interpolated(ref nt) => match &**nt {
554-
NtLiteral(_) => true,
555-
NtExpr(e) => match &e.kind {
554+
NtLiteral(..) => true,
555+
NtExpr(e, _) => match &e.kind {
556556
ast::ExprKind::Lit(_) => true,
557557
ast::ExprKind::Unary(ast::UnOp::Neg, e) => {
558558
matches!(&e.kind, ast::ExprKind::Lit(_))
@@ -572,10 +572,10 @@ impl Token {
572572
pub fn uninterpolate(&self) -> Cow<'_, Token> {
573573
match &self.kind {
574574
Interpolated(nt) => match **nt {
575-
NtIdent(ident, is_raw) => {
575+
NtIdent(ident, is_raw, _) => {
576576
Cow::Owned(Token::new(Ident(ident.name, is_raw), ident.span))
577577
}
578-
NtLifetime(ident) => Cow::Owned(Token::new(Lifetime(ident.name), ident.span)),
578+
NtLifetime(ident, _) => Cow::Owned(Token::new(Lifetime(ident.name), ident.span)),
579579
_ => Cow::Borrowed(self),
580580
},
581581
_ => Cow::Borrowed(self),
@@ -589,7 +589,7 @@ impl Token {
589589
match &self.kind {
590590
&Ident(name, is_raw) => Some((Ident::new(name, self.span), is_raw)),
591591
Interpolated(nt) => match **nt {
592-
NtIdent(ident, is_raw) => Some((ident, is_raw)),
592+
NtIdent(ident, is_raw, _) => Some((ident, is_raw)),
593593
_ => None,
594594
},
595595
_ => None,
@@ -603,7 +603,7 @@ impl Token {
603603
match &self.kind {
604604
&Lifetime(name) => Some(Ident::new(name, self.span)),
605605
Interpolated(nt) => match **nt {
606-
NtLifetime(ident) => Some(ident),
606+
NtLifetime(ident, _) => Some(ident),
607607
_ => None,
608608
},
609609
_ => None,
@@ -640,7 +640,7 @@ impl Token {
640640
/// (which happens while parsing the result of macro expansion)?
641641
pub fn is_whole_expr(&self) -> bool {
642642
if let Interpolated(nt) = &self.kind
643-
&& let NtExpr(_) | NtLiteral(_) | NtPath(_) | NtBlock(_) = **nt
643+
&& let NtExpr(..) | NtLiteral(..) | NtPath(..) | NtBlock(..) = **nt
644644
{
645645
return true;
646646
}
@@ -803,19 +803,19 @@ impl PartialEq<TokenKind> for Token {
803803
#[derive(Clone, Encodable, Decodable)]
804804
/// For interpolation during macro expansion.
805805
pub enum Nonterminal {
806-
NtItem(P<ast::Item>),
807-
NtBlock(P<ast::Block>),
808-
NtStmt(P<ast::Stmt>),
809-
NtPat(P<ast::Pat>),
810-
NtExpr(P<ast::Expr>),
811-
NtTy(P<ast::Ty>),
812-
NtIdent(Ident, /* is_raw */ bool),
813-
NtLifetime(Ident),
814-
NtLiteral(P<ast::Expr>),
806+
NtItem(P<ast::Item>, Span),
807+
NtBlock(P<ast::Block>, Span),
808+
NtStmt(P<ast::Stmt>, Span),
809+
NtPat(P<ast::Pat>, Span),
810+
NtExpr(P<ast::Expr>, Span),
811+
NtTy(P<ast::Ty>, Span),
812+
NtIdent(Ident, /* is_raw */ bool, Span),
813+
NtLifetime(Ident, Span),
814+
NtLiteral(P<ast::Expr>, Span),
815815
/// Stuff inside brackets for attributes
816-
NtMeta(P<ast::AttrItem>),
817-
NtPath(P<ast::Path>),
818-
NtVis(P<ast::Visibility>),
816+
NtMeta(P<ast::AttrItem>, Span),
817+
NtPath(P<ast::Path>, Span),
818+
NtVis(P<ast::Visibility>, Span),
819819
}
820820

821821
#[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable)]
@@ -897,29 +897,63 @@ impl fmt::Display for NonterminalKind {
897897
}
898898

899899
impl Nonterminal {
900-
pub fn span(&self) -> Span {
900+
pub fn use_span(&self) -> Span {
901901
match self {
902-
NtItem(item) => item.span,
903-
NtBlock(block) => block.span,
904-
NtStmt(stmt) => stmt.span,
905-
NtPat(pat) => pat.span,
906-
NtExpr(expr) | NtLiteral(expr) => expr.span,
907-
NtTy(ty) => ty.span,
908-
NtIdent(ident, _) | NtLifetime(ident) => ident.span,
909-
NtMeta(attr_item) => attr_item.span(),
910-
NtPath(path) => path.span,
911-
NtVis(vis) => vis.span,
902+
NtItem(item, _) => item.span,
903+
NtBlock(block, _) => block.span,
904+
NtStmt(stmt, _) => stmt.span,
905+
NtPat(pat, _) => pat.span,
906+
NtExpr(expr, _) | NtLiteral(expr, _) => expr.span,
907+
NtTy(ty, _) => ty.span,
908+
NtIdent(ident, _, _) | NtLifetime(ident, _) => ident.span,
909+
NtMeta(attr_item, _) => attr_item.span(),
910+
NtPath(path, _) => path.span,
911+
NtVis(vis, _) => vis.span,
912+
}
913+
}
914+
915+
pub fn def_span(&self) -> Span {
916+
match self {
917+
NtItem(_, span)
918+
| NtBlock(_, span)
919+
| NtStmt(_, span)
920+
| NtPat(_, span)
921+
| NtExpr(_, span)
922+
| NtLiteral(_, span)
923+
| NtTy(_, span)
924+
| NtIdent(_, _, span)
925+
| NtLifetime(_, span)
926+
| NtMeta(_, span)
927+
| NtPath(_, span)
928+
| NtVis(_, span) => *span,
929+
}
930+
}
931+
932+
pub fn descr(&self) -> &'static str {
933+
match self {
934+
NtItem(..) => "item",
935+
NtBlock(..) => "block",
936+
NtStmt(..) => "statement",
937+
NtPat(..) => "pattern",
938+
NtExpr(..) => "expression",
939+
NtLiteral(..) => "literal",
940+
NtTy(..) => "type",
941+
NtIdent(..) => "identifier",
942+
NtLifetime(..) => "lifetime",
943+
NtMeta(..) => "attribute",
944+
NtPath(..) => "path",
945+
NtVis(..) => "visibility",
912946
}
913947
}
914948
}
915949

916950
impl PartialEq for Nonterminal {
917951
fn eq(&self, rhs: &Self) -> bool {
918952
match (self, rhs) {
919-
(NtIdent(ident_lhs, is_raw_lhs), NtIdent(ident_rhs, is_raw_rhs)) => {
953+
(NtIdent(ident_lhs, is_raw_lhs, _), NtIdent(ident_rhs, is_raw_rhs, _)) => {
920954
ident_lhs == ident_rhs && is_raw_lhs == is_raw_rhs
921955
}
922-
(NtLifetime(ident_lhs), NtLifetime(ident_rhs)) => ident_lhs == ident_rhs,
956+
(NtLifetime(ident_lhs, _), NtLifetime(ident_rhs, _)) => ident_lhs == ident_rhs,
923957
// FIXME: Assume that all "complex" nonterminal are not equal, we can't compare them
924958
// correctly based on data from AST. This will prevent them from matching each other
925959
// in macros. The comparison will become possible only when each nonterminal has an
@@ -965,7 +999,7 @@ mod size_asserts {
965999
// tidy-alphabetical-start
9661000
static_assert_size!(Lit, 12);
9671001
static_assert_size!(LitKind, 2);
968-
static_assert_size!(Nonterminal, 16);
1002+
static_assert_size!(Nonterminal, 24);
9691003
static_assert_size!(Token, 24);
9701004
static_assert_size!(TokenKind, 16);
9711005
// tidy-alphabetical-end

compiler/rustc_ast/src/tokenstream.rs

+13-13
Original file line numberDiff line numberDiff line change
@@ -453,31 +453,31 @@ impl TokenStream {
453453

454454
pub fn from_nonterminal_ast(nt: &Nonterminal) -> TokenStream {
455455
match nt {
456-
Nonterminal::NtIdent(ident, is_raw) => {
456+
Nonterminal::NtIdent(ident, is_raw, _) => {
457457
TokenStream::token_alone(token::Ident(ident.name, *is_raw), ident.span)
458458
}
459-
Nonterminal::NtLifetime(ident) => {
459+
Nonterminal::NtLifetime(ident, _) => {
460460
TokenStream::token_alone(token::Lifetime(ident.name), ident.span)
461461
}
462-
Nonterminal::NtItem(item) => TokenStream::from_ast(item),
463-
Nonterminal::NtBlock(block) => TokenStream::from_ast(block),
464-
Nonterminal::NtStmt(stmt) if let StmtKind::Empty = stmt.kind => {
462+
Nonterminal::NtItem(item, _) => TokenStream::from_ast(item),
463+
Nonterminal::NtBlock(block, _) => TokenStream::from_ast(block),
464+
Nonterminal::NtStmt(stmt, _) if let StmtKind::Empty = stmt.kind => {
465465
// FIXME: Properly collect tokens for empty statements.
466466
TokenStream::token_alone(token::Semi, stmt.span)
467467
}
468-
Nonterminal::NtStmt(stmt) => TokenStream::from_ast(stmt),
469-
Nonterminal::NtPat(pat) => TokenStream::from_ast(pat),
470-
Nonterminal::NtTy(ty) => TokenStream::from_ast(ty),
471-
Nonterminal::NtMeta(attr) => TokenStream::from_ast(attr),
472-
Nonterminal::NtPath(path) => TokenStream::from_ast(path),
473-
Nonterminal::NtVis(vis) => TokenStream::from_ast(vis),
474-
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => TokenStream::from_ast(expr),
468+
Nonterminal::NtStmt(stmt, _) => TokenStream::from_ast(stmt),
469+
Nonterminal::NtPat(pat, _) => TokenStream::from_ast(pat),
470+
Nonterminal::NtTy(ty, _) => TokenStream::from_ast(ty),
471+
Nonterminal::NtMeta(attr, _) => TokenStream::from_ast(attr),
472+
Nonterminal::NtPath(path, _) => TokenStream::from_ast(path),
473+
Nonterminal::NtVis(vis, _) => TokenStream::from_ast(vis),
474+
Nonterminal::NtExpr(expr, _) | Nonterminal::NtLiteral(expr, _) => TokenStream::from_ast(expr),
475475
}
476476
}
477477

478478
fn flatten_token(token: &Token, spacing: Spacing) -> TokenTree {
479479
match &token.kind {
480-
token::Interpolated(nt) if let token::NtIdent(ident, is_raw) = **nt => {
480+
token::Interpolated(nt) if let token::NtIdent(ident, is_raw, _) = **nt => {
481481
TokenTree::Token(Token::new(token::Ident(ident.name, is_raw), ident.span), spacing)
482482
}
483483
token::Interpolated(nt) => TokenTree::Delimited(

compiler/rustc_ast_pretty/src/pprust/state.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -731,18 +731,18 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
731731

732732
fn nonterminal_to_string(&self, nt: &Nonterminal) -> String {
733733
match nt {
734-
token::NtExpr(e) => self.expr_to_string(e),
735-
token::NtMeta(e) => self.attr_item_to_string(e),
736-
token::NtTy(e) => self.ty_to_string(e),
737-
token::NtPath(e) => self.path_to_string(e),
738-
token::NtItem(e) => self.item_to_string(e),
739-
token::NtBlock(e) => self.block_to_string(e),
740-
token::NtStmt(e) => self.stmt_to_string(e),
741-
token::NtPat(e) => self.pat_to_string(e),
742-
token::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(*e, *is_raw).to_string(),
743-
token::NtLifetime(e) => e.to_string(),
744-
token::NtLiteral(e) => self.expr_to_string(e),
745-
token::NtVis(e) => self.vis_to_string(e),
734+
token::NtExpr(e, _) => self.expr_to_string(e),
735+
token::NtMeta(e, _) => self.attr_item_to_string(e),
736+
token::NtTy(e, _) => self.ty_to_string(e),
737+
token::NtPath(e, _) => self.path_to_string(e),
738+
token::NtItem(e, _) => self.item_to_string(e),
739+
token::NtBlock(e, _) => self.block_to_string(e),
740+
token::NtStmt(e, _) => self.stmt_to_string(e),
741+
token::NtPat(e, _) => self.pat_to_string(e),
742+
token::NtIdent(e, is_raw, _) => IdentPrinter::for_ast_ident(*e, *is_raw).to_string(),
743+
token::NtLifetime(e, _) => e.to_string(),
744+
token::NtLiteral(e, _) => self.expr_to_string(e),
745+
token::NtVis(e, _) => self.vis_to_string(e),
746746
}
747747
}
748748

compiler/rustc_expand/src/base.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1498,8 +1498,8 @@ pub(crate) fn ann_pretty_printing_compatibility_hack(ann: &Annotatable, sess: &P
14981498

14991499
pub(crate) fn nt_pretty_printing_compatibility_hack(nt: &Nonterminal, sess: &ParseSess) -> bool {
15001500
let item = match nt {
1501-
Nonterminal::NtItem(item) => item,
1502-
Nonterminal::NtStmt(stmt) => match &stmt.kind {
1501+
Nonterminal::NtItem(item, _) => item,
1502+
Nonterminal::NtStmt(stmt, _) => match &stmt.kind {
15031503
ast::StmtKind::Item(item) => item,
15041504
_ => return false,
15051505
},

0 commit comments

Comments
 (0)