diff options
| author | Nicholas Nethercote <n.nethercote@gmail.com> | 2022-04-21 13:49:40 +1000 |
|---|---|---|
| committer | Nicholas Nethercote <n.nethercote@gmail.com> | 2022-04-21 13:49:40 +1000 |
| commit | 643e9f707ed4ca13a158b6e290b424e520809ca6 (patch) | |
| tree | 7c737c276331b5891fabcd32be126ff1be6e7dff | |
| parent | cc4e3443ecf96f395e598b14af208d36a11ffb9f (diff) | |
| download | rust-643e9f707ed4ca13a158b6e290b424e520809ca6.tar.gz rust-643e9f707ed4ca13a158b6e290b424e520809ca6.zip | |
Introduced `Cursor::next_with_spacing_ref`.
This lets us clone just the parts within a `TokenTree` that need cloning, rather than the entire thing. This is a surprisingly large performance win, up to 4% on `async-std-1.10.0`.
| -rw-r--r-- | compiler/rustc_ast/src/tokenstream.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/mod.rs | 10 |
2 files changed, 13 insertions, 5 deletions
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 3321d3bf380..d609fa67205 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -583,6 +583,14 @@ impl Cursor { }) } + #[inline] + pub fn next_with_spacing_ref(&mut self) -> Option<&TreeAndSpacing> { + self.stream.0.get(self.index).map(|tree| { + self.index += 1; + tree + }) + } + pub fn index(&self) -> usize { self.index } diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index a620266247a..1686c5873e1 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -267,17 +267,17 @@ impl TokenCursor { // FIXME: we currently don't return `NoDelim` open/close delims. To fix #67062 we will // need to, whereupon the `delim != DelimToken::NoDelim` conditions below can be // removed, as well as the loop. - if let Some((tree, spacing)) = self.frame.tree_cursor.next_with_spacing() { + if let Some((tree, spacing)) = self.frame.tree_cursor.next_with_spacing_ref() { match tree { - TokenTree::Token(token) => match (desugar_doc_comments, &token) { + &TokenTree::Token(ref token) => match (desugar_doc_comments, token) { (true, &Token { kind: token::DocComment(_, attr_style, data), span }) => { return self.desugar(attr_style, data, span); } - _ => return (token, spacing), + _ => return (token.clone(), *spacing), }, - TokenTree::Delimited(sp, delim, tts) => { + &TokenTree::Delimited(sp, delim, ref tts) => { // Set `open_delim` to true here because we deal with it immediately. - let frame = TokenCursorFrame::new(sp, delim, tts); + let frame = TokenCursorFrame::new(sp, delim, tts.clone()); self.stack.push(mem::replace(&mut self.frame, frame)); if delim != DelimToken::NoDelim { return (Token::new(token::OpenDelim(delim), sp.open), Spacing::Alone); |
