Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit e97c945

Browse files
nnethercotecompiler-errors
authored andcommitted
Remove NtPat.
The one notable test change is `tests/ui/macros/trace_faulty_macros.rs`. This commit removes the complicated `Interpolated` handling in `expected_expression_found` that results in a longer error message. But I think the new, shorter message is actually an improvement. The original complaint was in rust-lang#71039, when the error message started with "error: expected expression, found `1 + 1`". That was confusing because `1 + 1` is an expression. Other than that, the reporter said "the whole error message is not too bad if you ignore the first line". Subsequently, extra complexity and wording was added to the error message. But I don't think the extra wording actually helps all that much. In particular, it still says of the `1+1` that "this is expected to be expression". This repeats the problem from the original complaint! This commit removes the extra complexity, reverting to a simpler error message. This is primarily because the traversal a pain without `Interpolated` tokens. Nonetheless, I think the error message is *improved*. It now starts with "expected expression, found `pat` metavariable", which is much clearer and the real problem. It also doesn't say anything specific about `1+1`, which is good, because the `1+1` isn't really relevant to the error -- it's the `$e:pat` that's important.
1 parent 23bb0bf commit e97c945

16 files changed

+66
-97
lines changed

compiler/rustc_ast/src/ast_traits.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,6 @@ impl HasTokens for Nonterminal {
202202
Nonterminal::NtItem(item) => item.tokens(),
203203
Nonterminal::NtStmt(stmt) => stmt.tokens(),
204204
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens(),
205-
Nonterminal::NtPat(pat) => pat.tokens(),
206205
Nonterminal::NtMeta(attr_item) => attr_item.tokens(),
207206
Nonterminal::NtPath(path) => path.tokens(),
208207
Nonterminal::NtBlock(block) => block.tokens(),
@@ -213,7 +212,6 @@ impl HasTokens for Nonterminal {
213212
Nonterminal::NtItem(item) => item.tokens_mut(),
214213
Nonterminal::NtStmt(stmt) => stmt.tokens_mut(),
215214
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens_mut(),
216-
Nonterminal::NtPat(pat) => pat.tokens_mut(),
217215
Nonterminal::NtMeta(attr_item) => attr_item.tokens_mut(),
218216
Nonterminal::NtPath(path) => path.tokens_mut(),
219217
Nonterminal::NtBlock(block) => block.tokens_mut(),

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,6 @@ fn visit_nonterminal<T: MutVisitor>(vis: &mut T, nt: &mut token::Nonterminal) {
813813
vis.flat_map_stmt(stmt).expect_one("expected visitor to produce exactly one item")
814814
})
815815
}),
816-
token::NtPat(pat) => vis.visit_pat(pat),
817816
token::NtExpr(expr) => vis.visit_expr(expr),
818817
token::NtLiteral(expr) => vis.visit_expr(expr),
819818
token::NtMeta(item) => {

compiler/rustc_ast/src/token.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,6 @@ impl Token {
652652
| NtExpr(..)
653653
| NtLiteral(..)
654654
| NtMeta(..)
655-
| NtPat(..)
656655
| NtPath(..)
657656
),
658657
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
@@ -1061,7 +1060,6 @@ pub enum Nonterminal {
10611060
NtItem(P<ast::Item>),
10621061
NtBlock(P<ast::Block>),
10631062
NtStmt(P<ast::Stmt>),
1064-
NtPat(P<ast::Pat>),
10651063
NtExpr(P<ast::Expr>),
10661064
NtLiteral(P<ast::Expr>),
10671065
/// Stuff inside brackets for attributes
@@ -1158,7 +1156,6 @@ impl Nonterminal {
11581156
NtItem(item) => item.span,
11591157
NtBlock(block) => block.span,
11601158
NtStmt(stmt) => stmt.span,
1161-
NtPat(pat) => pat.span,
11621159
NtExpr(expr) | NtLiteral(expr) => expr.span,
11631160
NtMeta(attr_item) => attr_item.span(),
11641161
NtPath(path) => path.span,
@@ -1170,7 +1167,6 @@ impl Nonterminal {
11701167
NtItem(..) => "item",
11711168
NtBlock(..) => "block",
11721169
NtStmt(..) => "statement",
1173-
NtPat(..) => "pattern",
11741170
NtExpr(..) => "expression",
11751171
NtLiteral(..) => "literal",
11761172
NtMeta(..) => "attribute",
@@ -1195,7 +1191,6 @@ impl fmt::Debug for Nonterminal {
11951191
NtItem(..) => f.pad("NtItem(..)"),
11961192
NtBlock(..) => f.pad("NtBlock(..)"),
11971193
NtStmt(..) => f.pad("NtStmt(..)"),
1198-
NtPat(..) => f.pad("NtPat(..)"),
11991194
NtExpr(..) => f.pad("NtExpr(..)"),
12001195
NtLiteral(..) => f.pad("NtLiteral(..)"),
12011196
NtMeta(..) => f.pad("NtMeta(..)"),

compiler/rustc_ast/src/tokenstream.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,6 @@ impl TokenStream {
468468
TokenStream::token_alone(token::Semi, stmt.span)
469469
}
470470
Nonterminal::NtStmt(stmt) => TokenStream::from_ast(stmt),
471-
Nonterminal::NtPat(pat) => TokenStream::from_ast(pat),
472471
Nonterminal::NtMeta(attr) => TokenStream::from_ast(attr),
473472
Nonterminal::NtPath(path) => TokenStream::from_ast(path),
474473
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => TokenStream::from_ast(expr),

compiler/rustc_expand/src/mbe/transcribe.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,9 @@ pub(super) fn transcribe<'a>(
303303
let kind = token::NtLifetime(*ident, *is_raw);
304304
TokenTree::token_alone(kind, sp)
305305
}
306+
MatchedSingle(ParseNtResult::Pat(pat, pat_kind)) => {
307+
mk_delimited(MetaVarKind::Pat(*pat_kind), TokenStream::from_ast(pat))
308+
}
306309
MatchedSingle(ParseNtResult::Ty(ty)) => {
307310
mk_delimited(MetaVarKind::Ty, TokenStream::from_ast(ty))
308311
}

compiler/rustc_parse/src/parser/diagnostics.rs

Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,11 @@ use ast::token::IdentIsRaw;
55
use rustc_ast as ast;
66
use rustc_ast::ptr::P;
77
use rustc_ast::token::{self, Delimiter, Lit, LitKind, Token, TokenKind};
8-
use rustc_ast::tokenstream::AttrTokenTree;
98
use rustc_ast::util::parser::AssocOp;
109
use rustc_ast::{
1110
AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingMode, Block,
12-
BlockCheckMode, Expr, ExprKind, GenericArg, Generics, HasTokens, Item, ItemKind, Param, Pat,
13-
PatKind, Path, PathSegment, QSelf, Recovered, Ty, TyKind,
11+
BlockCheckMode, Expr, ExprKind, GenericArg, Generics, Item, ItemKind, Param, Pat, PatKind,
12+
Path, PathSegment, QSelf, Recovered, Ty, TyKind,
1413
};
1514
use rustc_ast_pretty::pprust;
1615
use rustc_data_structures::fx::FxHashSet;
@@ -2426,52 +2425,6 @@ impl<'a> Parser<'a> {
24262425
err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
24272426
}
24282427
err.span_label(span, "expected expression");
2429-
2430-
// Walk the chain of macro expansions for the current token to point at how the original
2431-
// code was interpreted. This helps the user realize when a macro argument of one type is
2432-
// later reinterpreted as a different type, like `$x:expr` being reinterpreted as `$x:pat`
2433-
// in a subsequent macro invocation (#71039).
2434-
let mut tok = self.token.clone();
2435-
let mut labels = vec![];
2436-
while let TokenKind::Interpolated(nt) = &tok.kind {
2437-
let tokens = nt.tokens();
2438-
labels.push(nt.clone());
2439-
if let Some(tokens) = tokens
2440-
&& let tokens = tokens.to_attr_token_stream()
2441-
&& let tokens = tokens.0.deref()
2442-
&& let [AttrTokenTree::Token(token, _)] = &tokens[..]
2443-
{
2444-
tok = token.clone();
2445-
} else {
2446-
break;
2447-
}
2448-
}
2449-
let mut iter = labels.into_iter().peekable();
2450-
let mut show_link = false;
2451-
while let Some(nt) = iter.next() {
2452-
let descr = nt.descr();
2453-
if let Some(next) = iter.peek() {
2454-
let next_descr = next.descr();
2455-
if next_descr != descr {
2456-
err.span_label(next.use_span(), format!("this is expected to be {next_descr}"));
2457-
err.span_label(
2458-
nt.use_span(),
2459-
format!(
2460-
"this is interpreted as {}, but it is expected to be {}",
2461-
next_descr, descr,
2462-
),
2463-
);
2464-
show_link = true;
2465-
}
2466-
}
2467-
}
2468-
if show_link {
2469-
err.note(
2470-
"when forwarding a matched fragment to another macro-by-example, matchers in the \
2471-
second macro will see an opaque AST of the fragment type, not the underlying \
2472-
tokens",
2473-
);
2474-
}
24752428
err
24762429
}
24772430

compiler/rustc_parse/src/parser/item.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::mem;
44
use ast::token::IdentIsRaw;
55
use rustc_ast::ast::*;
66
use rustc_ast::ptr::P;
7-
use rustc_ast::token::{self, Delimiter, TokenKind};
7+
use rustc_ast::token::{self, Delimiter, InvisibleOrigin, MetaVarKind, TokenKind};
88
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
99
use rustc_ast::util::case::Case;
1010
use rustc_ast::{self as ast};
@@ -2976,8 +2976,10 @@ impl<'a> Parser<'a> {
29762976

29772977
fn is_named_param(&self) -> bool {
29782978
let offset = match &self.token.kind {
2979-
token::Interpolated(nt) => match &**nt {
2980-
token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon),
2979+
token::OpenDelim(Delimiter::Invisible(origin)) => match origin {
2980+
InvisibleOrigin::MetaVar(MetaVarKind::Pat(_)) => {
2981+
return self.check_noexpect_past_close_delim(&token::Colon);
2982+
}
29812983
_ => 0,
29822984
},
29832985
token::BinOp(token::And) | token::AndAnd => 1,

compiler/rustc_parse/src/parser/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ pub use pat::{CommaRecoveryMode, RecoverColon, RecoverComma};
2222
use path::PathStyle;
2323
use rustc_ast::ptr::P;
2424
use rustc_ast::token::{
25-
self, Delimiter, IdentIsRaw, InvisibleOrigin, MetaVarKind, Nonterminal, Token, TokenKind,
25+
self, Delimiter, IdentIsRaw, InvisibleOrigin, MetaVarKind, Nonterminal, NtPatKind, Token,
26+
TokenKind,
2627
};
2728
use rustc_ast::tokenstream::{
2829
AttrsTarget, DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree, TokenTreeCursor,
@@ -1747,6 +1748,7 @@ pub enum ParseNtResult {
17471748
Tt(TokenTree),
17481749
Ident(Ident, IdentIsRaw),
17491750
Lifetime(Ident, IdentIsRaw),
1751+
Pat(P<ast::Pat>, NtPatKind),
17501752
Ty(P<ast::Ty>),
17511753
Vis(P<ast::Visibility>),
17521754

compiler/rustc_parse/src/parser/nonterminal.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ impl<'a> Parser<'a> {
4949
fn nt_may_be_ident(nt: &Nonterminal) -> bool {
5050
match nt {
5151
NtStmt(_)
52-
| NtPat(_)
5352
| NtExpr(_)
5453
| NtLiteral(_) // `true`, `false`
5554
| NtMeta(_)
@@ -99,7 +98,7 @@ impl<'a> Parser<'a> {
9998
token::NtLifetime(..) => true,
10099
token::Interpolated(nt) => match &**nt {
101100
NtBlock(_) | NtStmt(_) | NtExpr(_) | NtLiteral(_) => true,
102-
NtItem(_) | NtPat(_) | NtMeta(_) | NtPath(_) => false,
101+
NtItem(_) | NtMeta(_) | NtPath(_) => false,
103102
},
104103
token::OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(k))) => match k {
105104
MetaVarKind::Block
@@ -170,15 +169,18 @@ impl<'a> Parser<'a> {
170169
}
171170
},
172171
NonterminalKind::Pat(pat_kind) => {
173-
NtPat(self.collect_tokens_no_attrs(|this| match pat_kind {
174-
PatParam { .. } => this.parse_pat_no_top_alt(None, None),
175-
PatWithOr => this.parse_pat_allow_top_alt(
176-
None,
177-
RecoverComma::No,
178-
RecoverColon::No,
179-
CommaRecoveryMode::EitherTupleOrPipe,
180-
),
181-
})?)
172+
return Ok(ParseNtResult::Pat(
173+
self.collect_tokens_no_attrs(|this| match pat_kind {
174+
PatParam { .. } => this.parse_pat_no_top_alt(None, None),
175+
PatWithOr => this.parse_pat_allow_top_alt(
176+
None,
177+
RecoverComma::No,
178+
RecoverColon::No,
179+
CommaRecoveryMode::EitherTupleOrPipe,
180+
),
181+
})?,
182+
pat_kind,
183+
));
182184
}
183185
NonterminalKind::Expr(_) => NtExpr(self.parse_expr_force_collect()?),
184186
NonterminalKind::Literal => {

compiler/rustc_parse/src/parser/pat.rs

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use rustc_ast::mut_visit::{walk_pat, MutVisitor};
22
use rustc_ast::ptr::P;
3-
use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token};
3+
use rustc_ast::token::NtPatKind::*;
4+
use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, MetaVarKind, Token};
45
use rustc_ast::{
56
self as ast, AttrVec, BindingMode, ByRef, Expr, ExprKind, MacCall, Mutability, Pat, PatField,
67
PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
@@ -25,8 +26,8 @@ use crate::errors::{
2526
UnexpectedParenInRangePat, UnexpectedParenInRangePatSugg,
2627
UnexpectedVertVertBeforeFunctionParam, UnexpectedVertVertInPattern, WrapInParens,
2728
};
29+
use crate::maybe_recover_from_interpolated_ty_qpath;
2830
use crate::parser::expr::could_be_unclosed_char_literal;
29-
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
3031

3132
#[derive(PartialEq, Copy, Clone)]
3233
pub enum Expected {
@@ -431,6 +432,27 @@ impl<'a> Parser<'a> {
431432
None
432433
}
433434

435+
fn eat_metavar_pat(&mut self) -> Option<P<Pat>> {
436+
// Must try both kinds of pattern nonterminals.
437+
if let Some(pat) = self.eat_metavar_seq_with_matcher(
438+
|mv_kind| matches!(mv_kind, MetaVarKind::Pat(PatParam { .. })),
439+
|this| this.parse_pat_no_top_alt(None, None),
440+
) {
441+
Some(pat)
442+
} else if let Some(pat) = self.eat_metavar_seq(MetaVarKind::Pat(PatWithOr), |this| {
443+
this.parse_pat_allow_top_alt(
444+
None,
445+
RecoverComma::No,
446+
RecoverColon::No,
447+
CommaRecoveryMode::EitherTupleOrPipe,
448+
)
449+
}) {
450+
Some(pat)
451+
} else {
452+
None
453+
}
454+
}
455+
434456
/// Parses a pattern, with a setting whether modern range patterns (e.g., `a..=b`, `a..b` are
435457
/// allowed).
436458
fn parse_pat_with_range_pat(
@@ -440,7 +462,10 @@ impl<'a> Parser<'a> {
440462
syntax_loc: Option<PatternLocation>,
441463
) -> PResult<'a, P<Pat>> {
442464
maybe_recover_from_interpolated_ty_qpath!(self, true);
443-
maybe_whole!(self, NtPat, |pat| pat);
465+
466+
if let Some(pat) = self.eat_metavar_pat() {
467+
return Ok(pat);
468+
}
444469

445470
let mut lo = self.token.span;
446471

@@ -776,10 +801,8 @@ impl<'a> Parser<'a> {
776801
self.recover_additional_muts();
777802

778803
// Make sure we don't allow e.g. `let mut $p;` where `$p:pat`.
779-
if let token::Interpolated(nt) = &self.token.kind {
780-
if let token::NtPat(..) = &**nt {
781-
self.expected_ident_found_err().emit();
782-
}
804+
if let Some(MetaVarKind::Pat(_)) = self.token.is_metavar_seq() {
805+
self.expected_ident_found_err().emit();
783806
}
784807

785808
// Parse the pattern we hope to be an identifier.

0 commit comments

Comments
 (0)