diff options
| author | Nicholas Nethercote <n.nethercote@gmail.com> | 2024-07-12 13:20:24 +1000 |
|---|---|---|
| committer | Nicholas Nethercote <n.nethercote@gmail.com> | 2024-07-12 13:35:24 +1000 |
| commit | 100f3fd133d928e9c86cff202fa32e5e4d0ce6c7 (patch) | |
| tree | ac48e5de185f654e0be0900b8bbadae3dd982269 /compiler/rustc_parse/src/parser/mod.rs | |
| parent | ebe1305b1e0bb32913b309ce65bd97106532ad6a (diff) | |
| download | rust-100f3fd133d928e9c86cff202fa32e5e4d0ce6c7.tar.gz rust-100f3fd133d928e9c86cff202fa32e5e4d0ce6c7.zip | |
Add a new special case to `Parser::look_ahead`.
This new special case is simpler than the old special case because it only is used when `dist == 1`. But that's still enough to cover ~98% of cases. This results in equivalent performance to the old special case, and identical behaviour as the general case.
Diffstat (limited to 'compiler/rustc_parse/src/parser/mod.rs')
| -rw-r--r-- | compiler/rustc_parse/src/parser/mod.rs | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index f906a2ecab7..ef9b3aabc61 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1118,6 +1118,35 @@ impl<'a> Parser<'a> { return looker(&self.token); } + // Typically around 98% of the `dist > 0` cases have `dist == 1`, so we + // have a fast special case for that. + if dist == 1 { + // The index is zero because the tree cursor's index always points + // to the next token to be gotten. + match self.token_cursor.tree_cursor.look_ahead(0) { + Some(tree) => { + // Indexing stayed within the current token tree. + return match tree { + TokenTree::Token(token, _) => looker(token), + TokenTree::Delimited(dspan, _, delim, _) => { + looker(&Token::new(token::OpenDelim(*delim), dspan.open)) + } + }; + } + None => { + // The tree cursor lookahead went (one) past the end of the + // current token tree. Try to return a close delimiter. + if let Some(&(_, span, _, delim)) = self.token_cursor.stack.last() + && delim != Delimiter::Invisible + { + // We are not in the outermost token stream, so we have + // delimiters. Also, those delimiters are not skipped. + return looker(&Token::new(token::CloseDelim(delim), span.close)); + } + } + } + } + // Just clone the token cursor and use `next`, skipping delimiters as // necessary. Slow but simple. let mut cursor = self.token_cursor.clone(); |
