Skip to content

Commit 100f3fd

Browse files
committed
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.
1 parent ebe1305 commit 100f3fd

File tree

1 file changed

+29
-0
lines changed
  • compiler/rustc_parse/src/parser

1 file changed

+29
-0
lines changed

compiler/rustc_parse/src/parser/mod.rs

+29
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,35 @@ impl<'a> Parser<'a> {
11181118
return looker(&self.token);
11191119
}
11201120

1121+
// Typically around 98% of the `dist > 0` cases have `dist == 1`, so we
1122+
// have a fast special case for that.
1123+
if dist == 1 {
1124+
// The index is zero because the tree cursor's index always points
1125+
// to the next token to be gotten.
1126+
match self.token_cursor.tree_cursor.look_ahead(0) {
1127+
Some(tree) => {
1128+
// Indexing stayed within the current token tree.
1129+
return match tree {
1130+
TokenTree::Token(token, _) => looker(token),
1131+
TokenTree::Delimited(dspan, _, delim, _) => {
1132+
looker(&Token::new(token::OpenDelim(*delim), dspan.open))
1133+
}
1134+
};
1135+
}
1136+
None => {
1137+
// The tree cursor lookahead went (one) past the end of the
1138+
// current token tree. Try to return a close delimiter.
1139+
if let Some(&(_, span, _, delim)) = self.token_cursor.stack.last()
1140+
&& delim != Delimiter::Invisible
1141+
{
1142+
// We are not in the outermost token stream, so we have
1143+
// delimiters. Also, those delimiters are not skipped.
1144+
return looker(&Token::new(token::CloseDelim(delim), span.close));
1145+
}
1146+
}
1147+
}
1148+
}
1149+
11211150
// Just clone the token cursor and use `next`, skipping delimiters as
11221151
// necessary. Slow but simple.
11231152
let mut cursor = self.token_cursor.clone();

0 commit comments

Comments
 (0)