Skip to content

Commit d9d405b

Browse files
committed
Remove NtVis.
We now use invisible delimiters for expanded `vis` fragments, instead of `Token::Interpolated`.
1 parent 860b041 commit d9d405b

File tree

10 files changed

+88
-36
lines changed

10 files changed

+88
-36
lines changed

compiler/rustc_ast/src/ast_traits.rs

-2
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,6 @@ impl HasTokens for Nonterminal {
238238
Nonterminal::NtTy(ty) => ty.tokens(),
239239
Nonterminal::NtMeta(attr_item) => attr_item.tokens(),
240240
Nonterminal::NtPath(path) => path.tokens(),
241-
Nonterminal::NtVis(vis) => vis.tokens(),
242241
Nonterminal::NtBlock(block) => block.tokens(),
243242
}
244243
}
@@ -251,7 +250,6 @@ impl HasTokens for Nonterminal {
251250
Nonterminal::NtTy(ty) => ty.tokens_mut(),
252251
Nonterminal::NtMeta(attr_item) => attr_item.tokens_mut(),
253252
Nonterminal::NtPath(path) => path.tokens_mut(),
254-
Nonterminal::NtVis(vis) => vis.tokens_mut(),
255253
Nonterminal::NtBlock(block) => block.tokens_mut(),
256254
}
257255
}

compiler/rustc_ast/src/mut_visit.rs

-1
Original file line numberDiff line numberDiff line change
@@ -846,7 +846,6 @@ fn visit_nonterminal<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut T) {
846846
visit_lazy_tts(tokens, vis);
847847
}
848848
token::NtPath(path) => vis.visit_path(path),
849-
token::NtVis(visib) => vis.visit_vis(visib),
850849
}
851850
}
852851

compiler/rustc_ast/src/token.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,15 @@ impl Token {
838838
}
839839
}
840840

841+
/// Is this an invisible open delimiter at the start of a token sequence
842+
/// from an expanded metavar?
843+
pub fn is_metavar_seq(&self) -> Option<NonterminalKind> {
844+
match self.kind {
845+
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(kind))) => Some(kind),
846+
_ => None,
847+
}
848+
}
849+
841850
pub fn glue(&self, joint: &Token) -> Option<Token> {
842851
let kind = match self.kind {
843852
Eq => match joint.kind {
@@ -920,7 +929,6 @@ pub enum Nonterminal {
920929
/// Stuff inside brackets for attributes
921930
NtMeta(P<ast::AttrItem>),
922931
NtPath(P<ast::Path>),
923-
NtVis(P<ast::Visibility>),
924932
}
925933

926934
#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, HashStable_Generic)]
@@ -1012,7 +1020,6 @@ impl Nonterminal {
10121020
NtTy(ty) => ty.span,
10131021
NtMeta(attr_item) => attr_item.span(),
10141022
NtPath(path) => path.span,
1015-
NtVis(vis) => vis.span,
10161023
}
10171024
}
10181025

@@ -1027,7 +1034,6 @@ impl Nonterminal {
10271034
NtTy(..) => "type",
10281035
NtMeta(..) => "attribute",
10291036
NtPath(..) => "path",
1030-
NtVis(..) => "visibility",
10311037
}
10321038
}
10331039
}
@@ -1054,7 +1060,6 @@ impl fmt::Debug for Nonterminal {
10541060
NtLiteral(..) => f.pad("NtLiteral(..)"),
10551061
NtMeta(..) => f.pad("NtMeta(..)"),
10561062
NtPath(..) => f.pad("NtPath(..)"),
1057-
NtVis(..) => f.pad("NtVis(..)"),
10581063
}
10591064
}
10601065
}

compiler/rustc_ast/src/tokenstream.rs

-1
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,6 @@ impl TokenStream {
477477
Nonterminal::NtTy(ty) => TokenStream::from_ast(ty),
478478
Nonterminal::NtMeta(attr) => TokenStream::from_ast(attr),
479479
Nonterminal::NtPath(path) => TokenStream::from_ast(path),
480-
Nonterminal::NtVis(vis) => TokenStream::from_ast(vis),
481480
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => TokenStream::from_ast(expr),
482481
}
483482
}

compiler/rustc_ast_pretty/src/pprust/state.rs

-1
Original file line numberDiff line numberDiff line change
@@ -862,7 +862,6 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
862862
token::NtStmt(e) => self.stmt_to_string(e),
863863
token::NtPat(e) => self.pat_to_string(e),
864864
token::NtLiteral(e) => self.expr_to_string(e),
865-
token::NtVis(e) => self.vis_to_string(e),
866865
}
867866
}
868867

compiler/rustc_expand/src/mbe/transcribe.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::errors::{
66
use crate::mbe::macro_parser::{NamedMatch, NamedMatch::*};
77
use crate::mbe::{self, KleeneOp, MetaVarExpr};
88
use rustc_ast::mut_visit::{self, MutVisitor};
9-
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
9+
use rustc_ast::token::{self, Delimiter, InvisibleOrigin, NonterminalKind, Token, TokenKind};
1010
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
1111
use rustc_data_structures::fx::FxHashMap;
1212
use rustc_errors::{pluralize, Diag, PResult};
@@ -249,12 +249,24 @@ pub(super) fn transcribe<'a>(
249249
}
250250
}
251251

252-
// Replace the meta-var with the matched token tree from the invocation.
253252
mbe::TokenTree::MetaVar(mut sp, mut original_ident) => {
254253
// Find the matched nonterminal from the macro invocation, and use it to replace
255254
// the meta-var.
256255
let ident = MacroRulesNormalizedIdent::new(original_ident);
257256
if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) {
257+
let mut mk_delimited = |nt_kind, stream| {
258+
// Emit as a token stream within `Delimiter::Invisible` to maintain parsing
259+
// priorities.
260+
marker.visit_span(&mut sp);
261+
// Both the open delim and close delim get the same span, which covers the
262+
// `$foo` in the decl macro RHS.
263+
TokenTree::Delimited(
264+
DelimSpan::from_single(sp),
265+
DelimSpacing::new(Spacing::Alone, Spacing::Alone),
266+
Delimiter::Invisible(InvisibleOrigin::MetaVar(nt_kind)),
267+
stream,
268+
)
269+
};
258270
let tt = match cur_matched {
259271
MatchedSingle(ParseNtResult::Tt(tt)) => {
260272
// `tt`s are emitted into the output stream directly as "raw tokens",
@@ -271,6 +283,9 @@ pub(super) fn transcribe<'a>(
271283
let kind = token::NtLifetime(*ident);
272284
TokenTree::token_alone(kind, sp)
273285
}
286+
MatchedSingle(ParseNtResult::Vis(ref vis)) => {
287+
mk_delimited(NonterminalKind::Vis, TokenStream::from_ast(vis))
288+
}
274289
MatchedSingle(ParseNtResult::Nt(nt)) => {
275290
// Other variables are emitted into the output stream as groups with
276291
// `Delimiter::Invisible` to maintain parsing priorities.

compiler/rustc_parse/src/parser/mod.rs

+44-2
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,39 @@ macro_rules! maybe_whole {
119119
};
120120
}
121121

122+
/// Reparses an invisible-delimited sequence produced by expansion of a
123+
/// declarative macro metavariable. Will panic if called with a `self.token`
124+
/// that is not an `InvisibleOrigin::Metavar` invisible open delimiter.
125+
#[macro_export]
126+
macro_rules! reparse_metavar_seq {
127+
($p:expr, $nt_kind:expr, $nt_res:pat, $ret:expr) => {{
128+
let delim = token::Delimiter::Invisible(token::InvisibleOrigin::MetaVar($nt_kind));
129+
$p.expect(&token::OpenDelim(delim)).expect("no open delim when reparsing");
130+
let Ok($nt_res) = $p.parse_nonterminal($nt_kind) else {
131+
panic!("failed to reparse");
132+
};
133+
$p.expect(&token::CloseDelim(delim)).expect("no close delim when reparsing");
134+
$ret
135+
}};
136+
}
137+
138+
/// Reparses an an invisible-delimited sequence produced by expansion of a
139+
/// declarative macro metavariable, if present.
140+
///
141+
/// `$nt_kind_pat` and `$nt_kind` are always syntactically identical in
142+
/// practice, but must be specified separately because one is a pattern and one
143+
/// is an expression. Which is annoying but hard to avoid.
144+
#[macro_export]
145+
macro_rules! maybe_reparse_metavar_seq {
146+
($p:expr, $nt_kind_pat:pat, $nt_kind:expr, $nt_res:pat, $ret:expr) => {
147+
if let Some($nt_kind_pat) = $p.token.is_metavar_seq() {
148+
Some(crate::reparse_metavar_seq!($p, $nt_kind, $nt_res, $ret))
149+
} else {
150+
None
151+
}
152+
};
153+
}
154+
122155
/// If the next tokens are ill-formed `$ty::` recover them as `<$ty>::`.
123156
#[macro_export]
124157
macro_rules! maybe_recover_from_interpolated_ty_qpath {
@@ -1426,7 +1459,15 @@ impl<'a> Parser<'a> {
14261459
/// so emit a proper diagnostic.
14271460
// Public for rustfmt usage.
14281461
pub fn parse_visibility(&mut self, fbt: FollowedByType) -> PResult<'a, Visibility> {
1429-
maybe_whole!(self, NtVis, |vis| vis.into_inner());
1462+
if let Some(vis) = maybe_reparse_metavar_seq!(
1463+
self,
1464+
NonterminalKind::Vis,
1465+
NonterminalKind::Vis,
1466+
ParseNtResult::Vis(vis),
1467+
vis
1468+
) {
1469+
return Ok(vis.into_inner());
1470+
}
14301471

14311472
if !self.eat_keyword(kw::Pub) {
14321473
// We need a span for our `Spanned<VisibilityKind>`, but there's inherently no
@@ -1650,7 +1691,8 @@ pub enum ParseNtResult {
16501691
Tt(TokenTree),
16511692
Ident(Ident, IdentIsRaw),
16521693
Lifetime(Ident),
1694+
Vis(P<ast::Visibility>),
16531695

1654-
/// This case will eventually be removed, along with `Token::Interpolate`.
1696+
/// This variant will eventually be removed, along with `Token::Interpolate`.
16551697
Nt(Lrc<Nonterminal>),
16561698
}

compiler/rustc_parse/src/parser/nonterminal.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,7 @@ impl<'a> Parser<'a> {
5454
| NtMeta(_)
5555
| NtPath(_) => true,
5656

57-
NtItem(_)
58-
| NtBlock(_)
59-
| NtVis(_) => false,
57+
NtItem(_) | NtBlock(_) => false,
6058
}
6159
}
6260

@@ -72,7 +70,7 @@ impl<'a> Parser<'a> {
7270
NonterminalKind::Ident => get_macro_ident(token).is_some(),
7371
NonterminalKind::Literal => token.can_begin_literal_maybe_minus(),
7472
NonterminalKind::Vis => match token.kind {
75-
// The follow-set of :vis + "priv" keyword + interpolated
73+
// The follow-set of :vis + "priv" keyword + interpolated/metavar-expansion.
7674
token::Comma
7775
| token::Ident(..)
7876
| token::NtIdent(..)
@@ -86,7 +84,7 @@ impl<'a> Parser<'a> {
8684
token::NtLifetime(..) => true,
8785
token::Interpolated(nt) => match &**nt {
8886
NtBlock(_) | NtStmt(_) | NtExpr(_) | NtLiteral(_) => true,
89-
NtItem(_) | NtPat(_) | NtTy(_) | NtMeta(_) | NtPath(_) | NtVis(_) => false,
87+
NtItem(_) | NtPat(_) | NtTy(_) | NtMeta(_) | NtPath(_) => false,
9088
},
9189
token::OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(k))) => match k {
9290
NonterminalKind::Block
@@ -218,8 +216,9 @@ impl<'a> Parser<'a> {
218216
}
219217
NonterminalKind::Meta => NtMeta(P(self.parse_attr_item(true)?)),
220218
NonterminalKind::Vis => {
221-
NtVis(P(self
222-
.collect_tokens_no_attrs(|this| this.parse_visibility(FollowedByType::Yes))?))
219+
return Ok(ParseNtResult::Vis(P(self.collect_tokens_no_attrs(|this| {
220+
this.parse_visibility(FollowedByType::Yes)
221+
})?)));
223222
}
224223
NonterminalKind::Lifetime => {
225224
return if self.check_lifetime() {

tests/ui/macros/stringify.rs

+11-15
Original file line numberDiff line numberDiff line change
@@ -864,23 +864,19 @@ fn test_ty() {
864864
#[test]
865865
fn test_vis() {
866866
// VisibilityKind::Public
867-
c2!(vis, [ pub ], "pub ", "pub");
867+
c1!(vis, [ pub ], "pub");
868868

869869
// VisibilityKind::Restricted
870-
c2!(vis, [ pub(crate) ], "pub(crate) ", "pub(crate)");
871-
c2!(vis, [ pub(self) ], "pub(self) ", "pub(self)");
872-
c2!(vis, [ pub(super) ], "pub(super) ", "pub(super)");
873-
c2!(vis, [ pub(in crate) ], "pub(in crate) ", "pub(in crate)");
874-
c2!(vis, [ pub(in self) ], "pub(in self) ", "pub(in self)");
875-
c2!(vis, [ pub(in super) ], "pub(in super) ", "pub(in super)");
876-
c2!(vis, [ pub(in path::to) ], "pub(in path::to) ", "pub(in path::to)");
877-
c2!(vis, [ pub(in ::path::to) ], "pub(in ::path::to) ", "pub(in ::path::to)");
878-
c2!(vis, [ pub(in self::path::to) ], "pub(in self::path::to) ", "pub(in self::path::to)");
879-
c2!(vis,
880-
[ pub(in super::path::to) ],
881-
"pub(in super::path::to) ",
882-
"pub(in super::path::to)"
883-
);
870+
c1!(vis, [ pub(crate) ], "pub(crate)");
871+
c1!(vis, [ pub(self) ], "pub(self)");
872+
c1!(vis, [ pub(super) ], "pub(super)");
873+
c1!(vis, [ pub(in crate) ], "pub(in crate)");
874+
c1!(vis, [ pub(in self) ], "pub(in self)");
875+
c1!(vis, [ pub(in super) ], "pub(in super)");
876+
c1!(vis, [ pub(in path::to) ], "pub(in path::to)");
877+
c1!(vis, [ pub(in ::path::to) ], "pub(in ::path::to)");
878+
c1!(vis, [ pub(in self::path::to) ], "pub(in self::path::to)");
879+
c1!(vis, [ pub(in super::path::to) ], "pub(in super::path::to)");
884880

885881
// VisibilityKind::Inherited
886882
// This one is different because directly calling `vis!` does not work.

tests/ui/proc-macro/capture-macro-rules-invoke.stdout

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
1212
},
1313
]
1414
PRINT-BANG INPUT (DISPLAY): 1 + 1, { "a" }, let a = 1;, String, my_name, 'a, my_val = 30,
15-
std::option::Option, pub(in some::path) , [a b c], -30
15+
std::option::Option, pub(in some::path), [a b c], -30
1616
PRINT-BANG RE-COLLECTED (DISPLAY): 1 + 1, { "a" }, let a = 1, String, my_name, 'a, my_val = 30,
1717
std::option::Option, pub(in some::path), [a b c], -30
1818
PRINT-BANG DEEP-RE-COLLECTED (DISPLAY): 1 + 1, { "a" }, let a = 1, String, my_name, 'a, my_val = 30,

0 commit comments

Comments
 (0)