Skip to content

Commit 4c79efb

Browse files
committed
Introduce InvisibleOrigin on invisible delimiters.
It's not used meaningfully yet, but will be needed to get rid of interpolated tokens.
1 parent 77e5b60 commit 4c79efb

File tree

9 files changed

+55
-26
lines changed

9 files changed

+55
-26
lines changed

compiler/rustc_ast/src/attr/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ impl MetaItemKind {
387387
tokens: &mut impl Iterator<Item = &'a TokenTree>,
388388
) -> Option<MetaItemKind> {
389389
match tokens.next() {
390-
Some(TokenTree::Delimited(.., Delimiter::Invisible, inner_tokens)) => {
390+
Some(TokenTree::Delimited(.., Delimiter::Invisible(_), inner_tokens)) => {
391391
MetaItemKind::name_value_from_tokens(&mut inner_tokens.trees())
392392
}
393393
Some(TokenTree::Token(token, _)) => {
@@ -524,7 +524,7 @@ impl NestedMetaItem {
524524
tokens.next();
525525
return Some(NestedMetaItem::Lit(lit));
526526
}
527-
Some(TokenTree::Delimited(.., Delimiter::Invisible, inner_tokens)) => {
527+
Some(TokenTree::Delimited(.., Delimiter::Invisible(_), inner_tokens)) => {
528528
tokens.next();
529529
return NestedMetaItem::from_tokens(&mut inner_tokens.trees().peekable());
530530
}

compiler/rustc_ast/src/token.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,20 @@ pub enum BinOpToken {
3939
Shr,
4040
}
4141

42+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Encodable, Decodable, Hash, HashStable_Generic)]
43+
pub enum InvisibleOrigin {
44+
// From the expansion of a metavariable in a declarative macro.
45+
MetaVar(NonterminalKind),
46+
47+
// Converted from `proc_macro::Delimiter` in
48+
// `proc_macro::Delimiter::to_internal`, i.e. returned by a proc macro.
49+
ProcMacro,
50+
51+
// Converted from `TokenKind::Interpolated` in
52+
// `TokenStream::flatten_token`. Treated similarly to `ProcMacro`.
53+
FlattenToken,
54+
}
55+
4256
/// Describes how a sequence of token trees is delimited.
4357
/// Cannot use `proc_macro::Delimiter` directly because this
4458
/// structure should implement some additional traits.
@@ -56,7 +70,22 @@ pub enum Delimiter {
5670
/// "macro variable" `$var`. It is important to preserve operator priorities in cases like
5771
/// `$var * 3` where `$var` is `1 + 2`.
5872
/// Invisible delimiters might not survive roundtrip of a token stream through a string.
59-
Invisible,
73+
Invisible(InvisibleOrigin),
74+
}
75+
76+
impl Delimiter {
77+
// Should the parser skip these delimiters? Only happens for certain kinds
78+
// of invisible delimiters. Ideally this function should eventually
79+
// disappear, and no invisible delimiters should be skipped.
80+
#[inline]
81+
pub fn skip(&self) -> bool {
82+
use InvisibleOrigin::*;
83+
match self {
84+
Delimiter::Parenthesis | Delimiter::Bracket | Delimiter::Brace => false,
85+
Delimiter::Invisible(MetaVar(_)) => false,
86+
Delimiter::Invisible(FlattenToken | ProcMacro) => true,
87+
}
88+
}
6089
}
6190

6291
// Note that the suffix is *not* considered when deciding the `LitKind` in this
@@ -866,7 +895,7 @@ pub enum Nonterminal {
866895
NtVis(P<ast::Visibility>),
867896
}
868897

869-
#[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable)]
898+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, HashStable_Generic)]
870899
pub enum NonterminalKind {
871900
Item,
872901
Block,

compiler/rustc_ast/src/tokenstream.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
1616
use crate::ast::{AttrStyle, StmtKind};
1717
use crate::ast_traits::{HasAttrs, HasSpan, HasTokens};
18-
use crate::token::{self, Delimiter, Nonterminal, Token, TokenKind};
18+
use crate::token::{self, Delimiter, InvisibleOrigin, Nonterminal, Token, TokenKind};
1919
use crate::AttrVec;
2020

2121
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -497,7 +497,7 @@ impl TokenStream {
497497
token::Interpolated(nt) => TokenTree::Delimited(
498498
DelimSpan::from_single(token.span),
499499
DelimSpacing::new(Spacing::JointHidden, spacing),
500-
Delimiter::Invisible,
500+
Delimiter::Invisible(InvisibleOrigin::FlattenToken),
501501
TokenStream::from_nonterminal_ast(&nt.0).flattened(),
502502
),
503503
_ => TokenTree::Token(token.clone(), spacing),

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -903,9 +903,8 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
903903
token::CloseDelim(Delimiter::Bracket) => "]".into(),
904904
token::OpenDelim(Delimiter::Brace) => "{".into(),
905905
token::CloseDelim(Delimiter::Brace) => "}".into(),
906-
token::OpenDelim(Delimiter::Invisible) | token::CloseDelim(Delimiter::Invisible) => {
907-
"".into()
908-
}
906+
token::OpenDelim(Delimiter::Invisible(_))
907+
| token::CloseDelim(Delimiter::Invisible(_)) => "".into(),
909908
token::Pound => "#".into(),
910909
token::Dollar => "$".into(),
911910
token::Question => "?".into(),

compiler/rustc_expand/src/mbe/macro_rules.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,7 @@ fn has_compile_error_macro(rhs: &mbe::TokenTree) -> bool {
700700
&& let mbe::TokenTree::Token(bang) = bang
701701
&& let TokenKind::Not = bang.kind
702702
&& let mbe::TokenTree::Delimited(.., del) = args
703-
&& del.delim != Delimiter::Invisible
703+
&& !del.delim.skip()
704704
{
705705
true
706706
} else {

compiler/rustc_expand/src/mbe/quoted.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,12 @@ fn parse_tree<'a>(
152152
// during parsing.
153153
let mut next = outer_trees.next();
154154
let mut trees: Box<dyn Iterator<Item = &tokenstream::TokenTree>>;
155-
if let Some(tokenstream::TokenTree::Delimited(.., Delimiter::Invisible, tts)) = next {
156-
trees = Box::new(tts.trees());
157-
next = trees.next();
158-
} else {
159-
trees = Box::new(outer_trees);
155+
match next {
156+
Some(tokenstream::TokenTree::Delimited(.., delim, tts)) if delim.skip() => {
157+
trees = Box::new(tts.trees());
158+
next = trees.next();
159+
}
160+
_ => trees = Box::new(outer_trees),
160161
}
161162

162163
match next {

compiler/rustc_expand/src/proc_macro_server.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl FromInternal<token::Delimiter> for Delimiter {
3535
token::Delimiter::Parenthesis => Delimiter::Parenthesis,
3636
token::Delimiter::Brace => Delimiter::Brace,
3737
token::Delimiter::Bracket => Delimiter::Bracket,
38-
token::Delimiter::Invisible => Delimiter::None,
38+
token::Delimiter::Invisible(_) => Delimiter::None,
3939
}
4040
}
4141
}
@@ -46,7 +46,7 @@ impl ToInternal<token::Delimiter> for Delimiter {
4646
Delimiter::Parenthesis => token::Delimiter::Parenthesis,
4747
Delimiter::Brace => token::Delimiter::Brace,
4848
Delimiter::Bracket => token::Delimiter::Bracket,
49-
Delimiter::None => token::Delimiter::Invisible,
49+
Delimiter::None => token::Delimiter::Invisible(token::InvisibleOrigin::ProcMacro),
5050
}
5151
}
5252
}

compiler/rustc_parse/src/parser/mod.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ impl TokenCursor {
273273
spacing,
274274
delim,
275275
));
276-
if delim != Delimiter::Invisible {
276+
if !delim.skip() {
277277
return (Token::new(token::OpenDelim(delim), sp.open), spacing.open);
278278
}
279279
// No open delimiter to return; continue on to the next iteration.
@@ -282,7 +282,7 @@ impl TokenCursor {
282282
} else if let Some((tree_cursor, span, spacing, delim)) = self.stack.pop() {
283283
// We have exhausted this token stream. Move back to its parent token stream.
284284
self.tree_cursor = tree_cursor;
285-
if delim != Delimiter::Invisible {
285+
if !delim.skip() {
286286
return (Token::new(token::CloseDelim(delim), span.close), spacing.close);
287287
}
288288
// No close delimiter to return; continue on to the next iteration.
@@ -1110,7 +1110,7 @@ impl<'a> Parser<'a> {
11101110
}
11111111
debug_assert!(!matches!(
11121112
next.0.kind,
1113-
token::OpenDelim(Delimiter::Invisible) | token::CloseDelim(Delimiter::Invisible)
1113+
token::OpenDelim(delim) | token::CloseDelim(delim) if delim.skip()
11141114
));
11151115
self.inlined_bump_with(next)
11161116
}
@@ -1124,17 +1124,17 @@ impl<'a> Parser<'a> {
11241124
}
11251125

11261126
if let Some(&(_, span, _, delim)) = self.token_cursor.stack.last()
1127-
&& delim != Delimiter::Invisible
1127+
&& !delim.skip()
11281128
{
11291129
// We are not in the outermost token stream, and the token stream
11301130
// we are in has non-skipped delimiters. Look for skipped
11311131
// delimiters in the lookahead range.
11321132
let tree_cursor = &self.token_cursor.tree_cursor;
1133-
let all_normal = (0..dist).all(|i| {
1133+
let any_skip = (0..dist).any(|i| {
11341134
let token = tree_cursor.look_ahead(i);
1135-
!matches!(token, Some(TokenTree::Delimited(.., Delimiter::Invisible, _)))
1135+
matches!(token, Some(TokenTree::Delimited(.., delim, _)) if delim.skip())
11361136
});
1137-
if all_normal {
1137+
if !any_skip {
11381138
// There were no skipped delimiters. Do lookahead by plain indexing.
11391139
return match tree_cursor.look_ahead(dist - 1) {
11401140
Some(tree) => {
@@ -1165,7 +1165,7 @@ impl<'a> Parser<'a> {
11651165
token = cursor.next().0;
11661166
if matches!(
11671167
token.kind,
1168-
token::OpenDelim(Delimiter::Invisible) | token::CloseDelim(Delimiter::Invisible)
1168+
token::OpenDelim(delim) | token::CloseDelim(delim) if delim.skip()
11691169
) {
11701170
continue;
11711171
}

src/tools/rustfmt/src/macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ fn delim_token_to_str(
587587
("{ ", " }")
588588
}
589589
}
590-
Delimiter::Invisible => unreachable!(),
590+
Delimiter::Invisible(_) => unreachable!(),
591591
};
592592
if use_multiple_lines {
593593
let indent_str = shape.indent.to_string_with_newline(context.config);

0 commit comments

Comments
 (0)