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

Commit 2845a1d

Browse files
committed
Remove NtItem and NtStmt.
This involves replacing `nt_pretty_printing_compatibility_hack` with `stream_pretty_printing_compatibility_hack`. The handling of statements in `transcribe` is slightly different to other nonterminal kinds, due to the lack of `from_ast` implementation for empty statements. Notable test changes: - `tests/ui/proc-macro/expand-to-derive.rs`: the diff looks large but the only difference is the insertion of a single invisible-delimited group around a metavar.
1 parent b526145 commit 2845a1d

File tree

17 files changed

+173
-134
lines changed

17 files changed

+173
-134
lines changed

compiler/rustc_ast/src/ast_traits.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,6 @@ impl HasTokens for Attribute {
199199
impl HasTokens for Nonterminal {
200200
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
201201
match self {
202-
Nonterminal::NtItem(item) => item.tokens(),
203-
Nonterminal::NtStmt(stmt) => stmt.tokens(),
204202
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens(),
205203
Nonterminal::NtMeta(attr_item) => attr_item.tokens(),
206204
Nonterminal::NtPath(path) => path.tokens(),
@@ -209,8 +207,6 @@ impl HasTokens for Nonterminal {
209207
}
210208
fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
211209
match self {
212-
Nonterminal::NtItem(item) => item.tokens_mut(),
213-
Nonterminal::NtStmt(stmt) => stmt.tokens_mut(),
214210
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens_mut(),
215211
Nonterminal::NtMeta(attr_item) => attr_item.tokens_mut(),
216212
Nonterminal::NtPath(path) => path.tokens_mut(),

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -800,19 +800,7 @@ pub fn visit_token<T: MutVisitor>(vis: &mut T, t: &mut Token) {
800800
// multiple items there....
801801
fn visit_nonterminal<T: MutVisitor>(vis: &mut T, nt: &mut token::Nonterminal) {
802802
match nt {
803-
token::NtItem(item) => visit_clobber(item, |item| {
804-
// This is probably okay, because the only visitors likely to
805-
// peek inside interpolated nodes will be renamings/markings,
806-
// which map single items to single items.
807-
vis.flat_map_item(item).expect_one("expected visitor to produce exactly one item")
808-
}),
809803
token::NtBlock(block) => vis.visit_block(block),
810-
token::NtStmt(stmt) => visit_clobber(stmt, |stmt| {
811-
// See reasoning above.
812-
stmt.map(|stmt| {
813-
vis.flat_map_stmt(stmt).expect_one("expected visitor to produce exactly one item")
814-
})
815-
}),
816804
token::NtExpr(expr) => vis.visit_expr(expr),
817805
token::NtLiteral(expr) => vis.visit_expr(expr),
818806
token::NtMeta(item) => {

compiler/rustc_ast/src/token.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,9 +1057,7 @@ pub enum NtExprKind {
10571057
#[derive(Clone, Encodable, Decodable)]
10581058
/// For interpolation during macro expansion.
10591059
pub enum Nonterminal {
1060-
NtItem(P<ast::Item>),
10611060
NtBlock(P<ast::Block>),
1062-
NtStmt(P<ast::Stmt>),
10631061
NtExpr(P<ast::Expr>),
10641062
NtLiteral(P<ast::Expr>),
10651063
/// Stuff inside brackets for attributes
@@ -1153,9 +1151,7 @@ impl fmt::Display for NonterminalKind {
11531151
impl Nonterminal {
11541152
pub fn use_span(&self) -> Span {
11551153
match self {
1156-
NtItem(item) => item.span,
11571154
NtBlock(block) => block.span,
1158-
NtStmt(stmt) => stmt.span,
11591155
NtExpr(expr) | NtLiteral(expr) => expr.span,
11601156
NtMeta(attr_item) => attr_item.span(),
11611157
NtPath(path) => path.span,
@@ -1164,9 +1160,7 @@ impl Nonterminal {
11641160

11651161
pub fn descr(&self) -> &'static str {
11661162
match self {
1167-
NtItem(..) => "item",
11681163
NtBlock(..) => "block",
1169-
NtStmt(..) => "statement",
11701164
NtExpr(..) => "expression",
11711165
NtLiteral(..) => "literal",
11721166
NtMeta(..) => "attribute",
@@ -1188,9 +1182,7 @@ impl PartialEq for Nonterminal {
11881182
impl fmt::Debug for Nonterminal {
11891183
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11901184
match *self {
1191-
NtItem(..) => f.pad("NtItem(..)"),
11921185
NtBlock(..) => f.pad("NtBlock(..)"),
1193-
NtStmt(..) => f.pad("NtStmt(..)"),
11941186
NtExpr(..) => f.pad("NtExpr(..)"),
11951187
NtLiteral(..) => f.pad("NtLiteral(..)"),
11961188
NtMeta(..) => f.pad("NtMeta(..)"),

compiler/rustc_ast/src/tokenstream.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic};
2222
use rustc_serialize::{Decodable, Encodable};
2323
use rustc_span::{sym, Span, SpanDecoder, SpanEncoder, Symbol, DUMMY_SP};
2424

25-
use crate::ast::{AttrStyle, StmtKind};
25+
use crate::ast::AttrStyle;
2626
use crate::ast_traits::{HasAttrs, HasTokens};
2727
use crate::token::{self, Delimiter, InvisibleOrigin, Nonterminal, Token, TokenKind};
2828
use crate::{AttrVec, Attribute};
@@ -461,13 +461,7 @@ impl TokenStream {
461461

462462
pub fn from_nonterminal_ast(nt: &Nonterminal) -> TokenStream {
463463
match nt {
464-
Nonterminal::NtItem(item) => TokenStream::from_ast(item),
465464
Nonterminal::NtBlock(block) => TokenStream::from_ast(block),
466-
Nonterminal::NtStmt(stmt) if let StmtKind::Empty = stmt.kind => {
467-
// FIXME: Properly collect tokens for empty statements.
468-
TokenStream::token_alone(token::Semi, stmt.span)
469-
}
470-
Nonterminal::NtStmt(stmt) => TokenStream::from_ast(stmt),
471465
Nonterminal::NtMeta(attr) => TokenStream::from_ast(attr),
472466
Nonterminal::NtPath(path) => TokenStream::from_ast(path),
473467
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => TokenStream::from_ast(expr),

compiler/rustc_builtin_macros/src/cfg_eval.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ impl CfgEval<'_> {
164164
},
165165
Annotatable::Stmt(_) => |parser| {
166166
Ok(Annotatable::Stmt(P(parser
167-
.parse_stmt_without_recovery(false, ForceCollect::Yes)?
167+
.parse_stmt_without_recovery(false, ForceCollect::Yes, false)?
168168
.unwrap())))
169169
},
170170
Annotatable::Expr(_) => {

compiler/rustc_expand/src/base.rs

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::rc::Rc;
55

66
use rustc_ast::attr::MarkedAttrs;
77
use rustc_ast::ptr::P;
8-
use rustc_ast::token::Nonterminal;
8+
use rustc_ast::token::MetaVarKind;
99
use rustc_ast::tokenstream::TokenStream;
1010
use rustc_ast::visit::{AssocCtxt, Visitor};
1111
use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind};
@@ -15,7 +15,7 @@ use rustc_data_structures::sync::{self, Lrc};
1515
use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed, PResult};
1616
use rustc_feature::Features;
1717
use rustc_lint_defs::{BufferedEarlyLint, RegisteredTools};
18-
use rustc_parse::parser::Parser;
18+
use rustc_parse::parser::{ForceCollect, Parser};
1919
use rustc_parse::MACRO_ARGUMENTS;
2020
use rustc_session::config::CollapseMacroDebuginfo;
2121
use rustc_session::parse::ParseSess;
@@ -1374,13 +1374,13 @@ pub fn parse_macro_name_and_helper_attrs(
13741374
/// If this item looks like a specific enums from `rental`, emit a fatal error.
13751375
/// See #73345 and #83125 for more details.
13761376
/// FIXME(#73933): Remove this eventually.
1377-
fn pretty_printing_compatibility_hack(item: &Item, sess: &Session) {
1377+
fn pretty_printing_compatibility_hack(item: &Item, psess: &ParseSess) {
13781378
let name = item.ident.name;
13791379
if name == sym::ProceduralMasqueradeDummyType
13801380
&& let ast::ItemKind::Enum(enum_def, _) = &item.kind
13811381
&& let [variant] = &*enum_def.variants
13821382
&& variant.ident.name == sym::Input
1383-
&& let FileName::Real(real) = sess.source_map().span_to_filename(item.ident.span)
1383+
&& let FileName::Real(real) = psess.source_map().span_to_filename(item.ident.span)
13841384
&& let Some(c) = real
13851385
.local_path()
13861386
.unwrap_or(Path::new(""))
@@ -1398,15 +1398,15 @@ fn pretty_printing_compatibility_hack(item: &Item, sess: &Session) {
13981398
};
13991399

14001400
if crate_matches {
1401-
sess.dcx().emit_fatal(errors::ProcMacroBackCompat {
1401+
psess.dcx().emit_fatal(errors::ProcMacroBackCompat {
14021402
crate_name: "rental".to_string(),
14031403
fixed_version: "0.5.6".to_string(),
14041404
});
14051405
}
14061406
}
14071407
}
14081408

1409-
pub(crate) fn ann_pretty_printing_compatibility_hack(ann: &Annotatable, sess: &Session) {
1409+
pub(crate) fn ann_pretty_printing_compatibility_hack(ann: &Annotatable, psess: &ParseSess) {
14101410
let item = match ann {
14111411
Annotatable::Item(item) => item,
14121412
Annotatable::Stmt(stmt) => match &stmt.kind {
@@ -1415,17 +1415,36 @@ pub(crate) fn ann_pretty_printing_compatibility_hack(ann: &Annotatable, sess: &S
14151415
},
14161416
_ => return,
14171417
};
1418-
pretty_printing_compatibility_hack(item, sess)
1418+
pretty_printing_compatibility_hack(item, psess)
14191419
}
14201420

1421-
pub(crate) fn nt_pretty_printing_compatibility_hack(nt: &Nonterminal, sess: &Session) {
1422-
let item = match nt {
1423-
Nonterminal::NtItem(item) => item,
1424-
Nonterminal::NtStmt(stmt) => match &stmt.kind {
1425-
ast::StmtKind::Item(item) => item,
1426-
_ => return,
1427-
},
1421+
pub(crate) fn stream_pretty_printing_compatibility_hack(
1422+
kind: MetaVarKind,
1423+
stream: &TokenStream,
1424+
psess: &ParseSess,
1425+
) {
1426+
let item = match kind {
1427+
MetaVarKind::Item => {
1428+
let mut parser = Parser::new(psess, stream.clone(), None);
1429+
// No need to collect tokens for this simple check.
1430+
parser
1431+
.parse_item(ForceCollect::No)
1432+
.expect("failed to reparse item")
1433+
.expect("an actual item")
1434+
}
1435+
MetaVarKind::Stmt => {
1436+
let mut parser = Parser::new(psess, stream.clone(), None);
1437+
// No need to collect tokens for this simple check.
1438+
let stmt = parser
1439+
.parse_stmt(ForceCollect::No)
1440+
.expect("failed to reparse")
1441+
.expect("an actual stmt");
1442+
match &stmt.kind {
1443+
ast::StmtKind::Item(item) => item.clone(),
1444+
_ => return,
1445+
}
1446+
}
14281447
_ => return,
14291448
};
1430-
pretty_printing_compatibility_hack(item, sess)
1449+
pretty_printing_compatibility_hack(&item, psess)
14311450
}

compiler/rustc_expand/src/mbe/transcribe.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_ast::token::{
66
TokenKind,
77
};
88
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
9-
use rustc_ast::ExprKind;
9+
use rustc_ast::{ExprKind, StmtKind};
1010
use rustc_data_structures::fx::FxHashMap;
1111
use rustc_errors::{pluralize, Diag, DiagCtxtHandle, PResult};
1212
use rustc_parse::lexer::nfc_normalize;
@@ -303,6 +303,18 @@ pub(super) fn transcribe<'a>(
303303
let kind = token::NtLifetime(*ident, *is_raw);
304304
TokenTree::token_alone(kind, sp)
305305
}
306+
MatchedSingle(ParseNtResult::Item(item)) => {
307+
mk_delimited(MetaVarKind::Item, TokenStream::from_ast(item))
308+
}
309+
MatchedSingle(ParseNtResult::Stmt(stmt)) => {
310+
let stream = if let StmtKind::Empty = stmt.kind {
311+
// FIXME: Properly collect tokens for empty statements.
312+
TokenStream::token_alone(token::Semi, stmt.span)
313+
} else {
314+
TokenStream::from_ast(stmt)
315+
};
316+
mk_delimited(MetaVarKind::Stmt, stream)
317+
}
306318
MatchedSingle(ParseNtResult::Pat(pat, pat_kind)) => {
307319
mk_delimited(MetaVarKind::Pat(*pat_kind), TokenStream::from_ast(pat))
308320
}

compiler/rustc_expand/src/proc_macro.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ impl MultiItemModifier for DeriveProcMacro {
122122
// We had a lint for a long time, but now we just emit a hard error.
123123
// Eventually we might remove the special case hard error check
124124
// altogether. See #73345.
125-
crate::base::ann_pretty_printing_compatibility_hack(&item, &ecx.sess);
125+
crate::base::ann_pretty_printing_compatibility_hack(&item, &ecx.sess.psess);
126126
let input = item.to_tokens();
127127
let stream = {
128128
let _timer =

compiler/rustc_expand/src/proc_macro_server.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,25 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre
116116

117117
while let Some(tree) = cursor.next() {
118118
let (Token { kind, span }, joint) = match tree.clone() {
119-
tokenstream::TokenTree::Delimited(span, _, delim, tts) => {
120-
let delimiter = pm::Delimiter::from_internal(delim);
119+
tokenstream::TokenTree::Delimited(span, _, delim, stream) => {
120+
// We used to have an alternative behaviour for crates that
121+
// needed it: a hack used to pass AST fragments to
122+
// attribute and derive macros as a single nonterminal
123+
// token instead of a token stream. Such token needs to be
124+
// "unwrapped" and not represented as a delimited group. We
125+
// had a lint for a long time, but now we just emit a hard
126+
// error. Eventually we might remove the special case hard
127+
// error check altogether. See #73345.
128+
if let Delimiter::Invisible(InvisibleOrigin::MetaVar(kind)) = delim {
129+
crate::base::stream_pretty_printing_compatibility_hack(
130+
kind,
131+
&stream,
132+
rustc.psess(),
133+
);
134+
}
121135
trees.push(TokenTree::Group(Group {
122-
delimiter,
123-
stream: Some(tts),
136+
delimiter: pm::Delimiter::from_internal(delim),
137+
stream: Some(stream),
124138
span: DelimSpan {
125139
open: span.open,
126140
close: span.close,
@@ -280,15 +294,6 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre
280294

281295
Interpolated(nt) => {
282296
let stream = TokenStream::from_nonterminal_ast(&nt);
283-
// We used to have an alternative behaviour for crates that
284-
// needed it: a hack used to pass AST fragments to
285-
// attribute and derive macros as a single nonterminal
286-
// token instead of a token stream. Such token needs to be
287-
// "unwrapped" and not represented as a delimited group. We
288-
// had a lint for a long time, but now we just emit a hard
289-
// error. Eventually we might remove the special case hard
290-
// error check altogether. See #73345.
291-
crate::base::nt_pretty_printing_compatibility_hack(&nt, rustc.ecx.sess);
292297
trees.push(TokenTree::Group(Group {
293298
delimiter: pm::Delimiter::None,
294299
stream: Some(stream),

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3067,7 +3067,7 @@ impl<'a> Parser<'a> {
30673067
}
30683068

30693069
self.restore_snapshot(pre_pat_snapshot);
3070-
match self.parse_stmt_without_recovery(true, ForceCollect::No) {
3070+
match self.parse_stmt_without_recovery(true, ForceCollect::No, false) {
30713071
// Consume statements for as long as possible.
30723072
Ok(Some(stmt)) => {
30733073
stmts.push(stmt);

0 commit comments

Comments
 (0)