diff options
| author | Nicholas Nethercote <n.nethercote@gmail.com> | 2022-04-20 12:22:42 +1000 |
|---|---|---|
| committer | Nicholas Nethercote <n.nethercote@gmail.com> | 2022-04-20 12:28:26 +1000 |
| commit | b09522a634f5c6c53dd01ad60a37b6503355ce88 (patch) | |
| tree | 7b793a4141b79ce978966e7903e34aed7f91c29a /compiler/rustc_parse/src | |
| parent | 3cd5e346170437f844d18c17d3f870dc4722c96a (diff) | |
| download | rust-b09522a634f5c6c53dd01ad60a37b6503355ce88.tar.gz rust-b09522a634f5c6c53dd01ad60a37b6503355ce88.zip | |
Remove the loop from `Parser::bump()`.
The loop is there to handle a `NoDelim` open/close token. This commit changes `TokenCursor::inlined_next` so it never returns such a token. This is a performance win because the conditional test in `bump()` is removed. If the parser needs changing in the future to handle `NoDelim` tokens, then `inlined_next()` can easily be changed to return them.
Diffstat (limited to 'compiler/rustc_parse/src')
| -rw-r--r-- | compiler/rustc_parse/src/parser/mod.rs | 63 |
1 files changed, 34 insertions, 29 deletions
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index a276fb53895..173e0c2d529 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -242,12 +242,17 @@ struct TokenCursorFrame { delim: token::DelimToken, span: DelimSpan, tree_cursor: tokenstream::Cursor, - close_delim: bool, + need_to_produce_close_delim: bool, } impl TokenCursorFrame { - fn new(span: DelimSpan, delim: DelimToken, tts: TokenStream, close_delim: bool) -> Self { - TokenCursorFrame { delim, span, tree_cursor: tts.into_trees(), close_delim } + fn new(span: DelimSpan, delim: DelimToken, tts: TokenStream) -> Self { + TokenCursorFrame { + delim, + span, + tree_cursor: tts.into_trees(), + need_to_produce_close_delim: delim != DelimToken::NoDelim, + } } } @@ -261,28 +266,32 @@ impl TokenCursor { fn inlined_next(&mut self, desugar_doc_comments: bool) -> (Token, Spacing) { loop { if let Some((tree, spacing)) = self.frame.tree_cursor.next_with_spacing() { - return match tree { + match tree { TokenTree::Token(token) => match (desugar_doc_comments, &token) { (true, &Token { kind: token::DocComment(_, attr_style, data), span }) => { - self.desugar(attr_style, data, span) + return self.desugar(attr_style, data, span); } - _ => (token, spacing), + _ => return (token, spacing), }, TokenTree::Delimited(sp, delim, tts) => { // Set `open_delim` to true here because we deal with it immediately. - let frame = TokenCursorFrame::new(sp, delim, tts, false); + let frame = TokenCursorFrame::new(sp, delim, tts); self.stack.push(mem::replace(&mut self.frame, frame)); - (Token::new(token::OpenDelim(delim), sp.open), Spacing::Alone) + if delim != DelimToken::NoDelim { + return (Token::new(token::OpenDelim(delim), sp.open), Spacing::Alone); + } + // No open delimeter to return; continue on to the next iteration. } }; - } else if !self.frame.close_delim { - self.frame.close_delim = true; + } else if self.frame.need_to_produce_close_delim { + self.frame.need_to_produce_close_delim = false; return ( Token::new(token::CloseDelim(self.frame.delim), self.frame.span.close), Spacing::Alone, ); } else if let Some(frame) = self.stack.pop() { self.frame = frame; + // Back to the parent frame; continue on to the next iteration. } else { return (Token::new(token::Eof, DUMMY_SP), Spacing::Alone); } @@ -333,7 +342,6 @@ impl TokenCursor { .cloned() .collect::<TokenStream>() }, - true, ), )); @@ -422,7 +430,7 @@ impl<'a> Parser<'a> { desugar_doc_comments: bool, subparser_name: Option<&'static str>, ) -> Self { - let start_frame = TokenCursorFrame::new(DelimSpan::dummy(), token::NoDelim, tokens, true); + let start_frame = TokenCursorFrame::new(DelimSpan::dummy(), token::NoDelim, tokens); let mut parser = Parser { sess, @@ -993,24 +1001,21 @@ impl<'a> Parser<'a> { /// Advance the parser by one token. pub fn bump(&mut self) { let fallback_span = self.token.span; - loop { - let (mut next, spacing) = self.token_cursor.inlined_next(self.desugar_doc_comments); - self.token_cursor.num_next_calls += 1; - // We've retrieved an token from the underlying - // cursor, so we no longer need to worry about - // an unglued token. See `break_and_eat` for more details - self.token_cursor.break_last_token = false; - if next.span.is_dummy() { - // Tweak the location for better diagnostics, but keep syntactic context intact. - next.span = fallback_span.with_ctxt(next.span.ctxt()); - } - if !matches!( - next.kind, - token::OpenDelim(token::NoDelim) | token::CloseDelim(token::NoDelim) - ) { - return self.inlined_bump_with((next, spacing)); - } + let (mut next, spacing) = self.token_cursor.inlined_next(self.desugar_doc_comments); + self.token_cursor.num_next_calls += 1; + // We've retrieved an token from the underlying + // cursor, so we no longer need to worry about + // an unglued token. See `break_and_eat` for more details + self.token_cursor.break_last_token = false; + if next.span.is_dummy() { + // Tweak the location for better diagnostics, but keep syntactic context intact. + next.span = fallback_span.with_ctxt(next.span.ctxt()); } + debug_assert!(!matches!( + next.kind, + token::OpenDelim(token::NoDelim) | token::CloseDelim(token::NoDelim) + )); + self.inlined_bump_with((next, spacing)) } /// Look-ahead `dist` tokens of `self.token` and get access to that token there. |
