Skip to content

Commit b5ecbbb

Browse files
committed
Remove TokenCursorFrame.
The motivation here is to eliminate the `Option<(Delimiter, DelimSpan)>`, which is `None` for the outermost token stream and `Some` for all other token streams. We are already treating the innermost frame specially -- this is the `frame` vs `stack` distinction in `TokenCursor`. We can push that further so that `frame` only contains the cursor, and `stack` elements contain the delimiters for their children. When we are in the outermost token stream `stack` is empty, so there are no stored delimiters, which is what we want because the outermost token stream *has* no delimiters. This change also shrinks `TokenCursor`, which shrinks `Parser` and `LazyAttrTokenStreamImpl`, which is nice.
1 parent b23f272 commit b5ecbbb

File tree

3 files changed

+34
-42
lines changed

3 files changed

+34
-42
lines changed

compiler/rustc_parse/src/parser/attr_wrapper.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,6 @@ mod size_asserts {
469469
use rustc_data_structures::static_assert_size;
470470
// tidy-alphabetical-start
471471
static_assert_size!(AttrWrapper, 16);
472-
static_assert_size!(LazyAttrTokenStreamImpl, 144);
472+
static_assert_size!(LazyAttrTokenStreamImpl, 120);
473473
// tidy-alphabetical-end
474474
}

compiler/rustc_parse/src/parser/expr.rs

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

21432143
if self.token.kind == TokenKind::Semi
2144-
&& matches!(self.token_cursor.frame.delim_sp, Some((Delimiter::Parenthesis, _)))
2144+
&& matches!(self.token_cursor.stack.last(), Some((_, Delimiter::Parenthesis, _)))
21452145
&& self.may_recover()
21462146
{
21472147
// It is likely that the closure body is a block but where the

compiler/rustc_parse/src/parser/mod.rs

Lines changed: 32 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ pub struct Parser<'a> {
168168
// This type is used a lot, e.g. it's cloned when matching many declarative macro rules with nonterminals. Make sure
169169
// it doesn't unintentionally get bigger.
170170
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
171-
rustc_data_structures::static_assert_size!(Parser<'_>, 336);
171+
rustc_data_structures::static_assert_size!(Parser<'_>, 312);
172172

173173
/// Stores span information about a closure.
174174
#[derive(Clone)]
@@ -223,16 +223,21 @@ impl<'a> Drop for Parser<'a> {
223223

224224
#[derive(Clone)]
225225
struct TokenCursor {
226-
// The current (innermost) frame. `frame` and `stack` could be combined,
227-
// but it's faster to keep them separate and access `frame` directly
228-
// rather than via something like `stack.last().unwrap()` or
229-
// `stack[stack.len() - 1]`.
230-
frame: TokenCursorFrame,
231-
// Additional frames that enclose `frame`.
232-
stack: Vec<TokenCursorFrame>,
226+
// Cursor for the current (innermost) token stream. The delimiters for this
227+
// token stream are found in `self.stack.last()`; when that is `None` then
228+
// we are in the outermost token stream which never has delimiters.
229+
tree_cursor: tokenstream::Cursor,
230+
231+
// Token streams surrounding the current one. The delimiters for stack[n]'s
232+
// tokens are in `stack[n-1]`. `stack[0]` (when present) has no delimiters
233+
// because it's the outermost token stream which never has delimiters.
234+
stack: Vec<(tokenstream::Cursor, Delimiter, DelimSpan)>,
235+
233236
desugar_doc_comments: bool,
237+
234238
// Counts the number of calls to `{,inlined_}next`.
235239
num_next_calls: usize,
240+
236241
// During parsing, we may sometimes need to 'unglue' a
237242
// glued token into two component tokens
238243
// (e.g. '>>' into '>' and '>), so that the parser
@@ -257,19 +262,6 @@ struct TokenCursor {
257262
break_last_token: bool,
258263
}
259264

260-
#[derive(Clone)]
261-
struct TokenCursorFrame {
262-
// This is `None` only for the outermost frame.
263-
delim_sp: Option<(Delimiter, DelimSpan)>,
264-
tree_cursor: tokenstream::Cursor,
265-
}
266-
267-
impl TokenCursorFrame {
268-
fn new(delim_sp: Option<(Delimiter, DelimSpan)>, tts: TokenStream) -> Self {
269-
TokenCursorFrame { delim_sp, tree_cursor: tts.into_trees() }
270-
}
271-
}
272-
273265
impl TokenCursor {
274266
fn next(&mut self, desugar_doc_comments: bool) -> (Token, Spacing) {
275267
self.inlined_next(desugar_doc_comments)
@@ -282,12 +274,12 @@ impl TokenCursor {
282274
// FIXME: we currently don't return `Delimiter` open/close delims. To fix #67062 we will
283275
// need to, whereupon the `delim != Delimiter::Invisible` conditions below can be
284276
// removed.
285-
if let Some(tree) = self.frame.tree_cursor.next_ref() {
277+
if let Some(tree) = self.tree_cursor.next_ref() {
286278
match tree {
287279
&TokenTree::Token(ref token, spacing) => match (desugar_doc_comments, token) {
288280
(true, &Token { kind: token::DocComment(_, attr_style, data), span }) => {
289281
let desugared = self.desugar(attr_style, data, span);
290-
self.frame.tree_cursor.replace_prev_and_rewind(desugared);
282+
self.tree_cursor.replace_prev_and_rewind(desugared);
291283
// Continue to get the first token of the desugared doc comment.
292284
}
293285
_ => {
@@ -299,25 +291,23 @@ impl TokenCursor {
299291
}
300292
},
301293
&TokenTree::Delimited(sp, delim, ref tts) => {
302-
// Set `open_delim` to true here because we deal with it immediately.
303-
let frame = TokenCursorFrame::new(Some((delim, sp)), tts.clone());
304-
self.stack.push(mem::replace(&mut self.frame, frame));
294+
let trees = tts.clone().into_trees();
295+
self.stack.push((mem::replace(&mut self.tree_cursor, trees), delim, sp));
305296
if delim != Delimiter::Invisible {
306297
return (Token::new(token::OpenDelim(delim), sp.open), Spacing::Alone);
307298
}
308299
// No open delimiter to return; continue on to the next iteration.
309300
}
310301
};
311-
} else if let Some(frame) = self.stack.pop() {
312-
// We have exhausted this frame. Move back to its parent frame.
313-
let (delim, span) = self.frame.delim_sp.unwrap();
314-
self.frame = frame;
302+
} else if let Some((tree_cursor, delim, span)) = self.stack.pop() {
303+
// We have exhausted this token stream. Move back to its parent token stream.
304+
self.tree_cursor = tree_cursor;
315305
if delim != Delimiter::Invisible {
316306
return (Token::new(token::CloseDelim(delim), span.close), Spacing::Alone);
317307
}
318308
// No close delimiter to return; continue on to the next iteration.
319309
} else {
320-
// We have exhausted the outermost frame.
310+
// We have exhausted the outermost token stream.
321311
return (Token::new(token::Eof, DUMMY_SP), Spacing::Alone);
322312
}
323313
}
@@ -475,7 +465,7 @@ impl<'a> Parser<'a> {
475465
restrictions: Restrictions::empty(),
476466
expected_tokens: Vec::new(),
477467
token_cursor: TokenCursor {
478-
frame: TokenCursorFrame::new(None, tokens),
468+
tree_cursor: tokens.into_trees(),
479469
stack: Vec::new(),
480470
num_next_calls: 0,
481471
desugar_doc_comments,
@@ -1142,14 +1132,16 @@ impl<'a> Parser<'a> {
11421132
return looker(&self.token);
11431133
}
11441134

1145-
let frame = &self.token_cursor.frame;
1146-
if let Some((delim, span)) = frame.delim_sp && delim != Delimiter::Invisible {
1135+
let tree_cursor = &self.token_cursor.tree_cursor;
1136+
if let Some(&(_, delim, span)) = self.token_cursor.stack.last()
1137+
&& delim != Delimiter::Invisible
1138+
{
11471139
let all_normal = (0..dist).all(|i| {
1148-
let token = frame.tree_cursor.look_ahead(i);
1140+
let token = tree_cursor.look_ahead(i);
11491141
!matches!(token, Some(TokenTree::Delimited(_, Delimiter::Invisible, _)))
11501142
});
11511143
if all_normal {
1152-
return match frame.tree_cursor.look_ahead(dist - 1) {
1144+
return match tree_cursor.look_ahead(dist - 1) {
11531145
Some(tree) => match tree {
11541146
TokenTree::Token(token, _) => looker(token),
11551147
TokenTree::Delimited(dspan, delim, _) => {
@@ -1310,10 +1302,10 @@ impl<'a> Parser<'a> {
13101302
pub(crate) fn parse_token_tree(&mut self) -> TokenTree {
13111303
match self.token.kind {
13121304
token::OpenDelim(..) => {
1313-
// Grab the tokens from this frame.
1314-
let frame = &self.token_cursor.frame;
1315-
let stream = frame.tree_cursor.stream.clone();
1316-
let (delim, span) = frame.delim_sp.unwrap();
1305+
// Grab the tokens within the delimiters.
1306+
let tree_cursor = &self.token_cursor.tree_cursor;
1307+
let stream = tree_cursor.stream.clone();
1308+
let (_, delim, span) = *self.token_cursor.stack.last().unwrap();
13171309

13181310
// Advance the token cursor through the entire delimited
13191311
// sequence. After getting the `OpenDelim` we are *within* the

0 commit comments

Comments
 (0)