diff options
| author | Nicholas Nethercote <n.nethercote@gmail.com> | 2025-08-12 09:28:35 +1000 |
|---|---|---|
| committer | Nicholas Nethercote <n.nethercote@gmail.com> | 2025-08-14 15:31:29 +1000 |
| commit | 145b84721aae8e62d90b0fe40e8f796289ff7303 (patch) | |
| tree | a52327d35782b43f7d9e8e12616e647a995e9d48 | |
| parent | 2fd855fbfc8239285aa2d596f76a8cc75e17ce02 (diff) | |
| download | rust-145b84721aae8e62d90b0fe40e8f796289ff7303.tar.gz rust-145b84721aae8e62d90b0fe40e8f796289ff7303.zip | |
Sometimes skip over tokens in `parse_token_tree`.
This sometimes avoids a lot of `bump` calls.
| -rw-r--r-- | compiler/rustc_ast/src/tokenstream.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/mod.rs | 23 |
2 files changed, 23 insertions, 6 deletions
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index e55399adfb8..f4f35a4d2ee 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -907,6 +907,12 @@ impl TokenTreeCursor { pub fn bump(&mut self) { self.index += 1; } + + // For skipping ahead in rare circumstances. + #[inline] + pub fn bump_to_end(&mut self) { + self.index = self.stream.len(); + } } /// A `TokenStream` cursor that produces `Token`s. It's a bit odd that diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 90491e53249..3be575c6b15 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1389,15 +1389,26 @@ impl<'a> Parser<'a> { // matching `CloseDelim` we are *after* the delimited sequence, // i.e. at depth `d - 1`. let target_depth = self.token_cursor.stack.len() - 1; - loop { - // Advance one token at a time, so `TokenCursor::next()` - // can capture these tokens if necessary. + + if let Capturing::No = self.capture_state.capturing { + // We are not capturing tokens, so skip to the end of the + // delimited sequence. This is a perf win when dealing with + // declarative macros that pass large `tt` fragments through + // multiple rules, as seen in the uom-0.37.0 crate. + self.token_cursor.curr.bump_to_end(); self.bump(); - if self.token_cursor.stack.len() == target_depth { - debug_assert!(self.token.kind.close_delim().is_some()); - break; + debug_assert_eq!(self.token_cursor.stack.len(), target_depth); + } else { + loop { + // Advance one token at a time, so `TokenCursor::next()` + // can capture these tokens if necessary. + self.bump(); + if self.token_cursor.stack.len() == target_depth { + break; + } } } + debug_assert!(self.token.kind.close_delim().is_some()); // Consume close delimiter self.bump(); |
