Skip to content

Commit d2f7f67

Browse files
committed
Avoid some token tree cloning in decl macro parsing.
By changing `into_trees` into `trees`. Some of the subsequent paths require explicit clones, but not all.
1 parent 853f453 commit d2f7f67

File tree

2 files changed

+23
-23
lines changed

2 files changed

+23
-23
lines changed

compiler/rustc_expand/src/mbe/macro_rules.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ pub fn compile_declarative_macro(
500500
.map(|m| {
501501
if let MatchedTokenTree(tt) = m {
502502
let tt = mbe::quoted::parse(
503-
TokenStream::new(vec![tt.clone()]),
503+
&TokenStream::new(vec![tt.clone()]),
504504
true,
505505
&sess.parse_sess,
506506
def.id,
@@ -524,7 +524,7 @@ pub fn compile_declarative_macro(
524524
.map(|m| {
525525
if let MatchedTokenTree(tt) = m {
526526
return mbe::quoted::parse(
527-
TokenStream::new(vec![tt.clone()]),
527+
&TokenStream::new(vec![tt.clone()]),
528528
false,
529529
&sess.parse_sess,
530530
def.id,

compiler/rustc_expand/src/mbe/quoted.rs

+21-21
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
3636
///
3737
/// A collection of `self::TokenTree`. There may also be some errors emitted to `sess`.
3838
pub(super) fn parse(
39-
input: tokenstream::TokenStream,
39+
input: &tokenstream::TokenStream,
4040
parsing_patterns: bool,
4141
sess: &ParseSess,
4242
node_id: NodeId,
@@ -48,15 +48,15 @@ pub(super) fn parse(
4848

4949
// For each token tree in `input`, parse the token into a `self::TokenTree`, consuming
5050
// additional trees if need be.
51-
let mut trees = input.into_trees();
51+
let mut trees = input.trees();
5252
while let Some(tree) = trees.next() {
5353
// Given the parsed tree, if there is a metavar and we are expecting matchers, actually
5454
// parse out the matcher (i.e., in `$id:ident` this would parse the `:` and `ident`).
5555
let tree = parse_tree(tree, &mut trees, parsing_patterns, sess, node_id, features, edition);
5656
match tree {
5757
TokenTree::MetaVar(start_sp, ident) if parsing_patterns => {
5858
let span = match trees.next() {
59-
Some(tokenstream::TokenTree::Token(Token { kind: token::Colon, span }, _)) => {
59+
Some(&tokenstream::TokenTree::Token(Token { kind: token::Colon, span }, _)) => {
6060
match trees.next() {
6161
Some(tokenstream::TokenTree::Token(token, _)) => match token.ident() {
6262
Some((frag, _)) => {
@@ -96,10 +96,10 @@ pub(super) fn parse(
9696
}
9797
_ => token.span,
9898
},
99-
tree => tree.as_ref().map_or(span, tokenstream::TokenTree::span),
99+
tree => tree.map_or(span, tokenstream::TokenTree::span),
100100
}
101101
}
102-
tree => tree.as_ref().map_or(start_sp, tokenstream::TokenTree::span),
102+
tree => tree.map_or(start_sp, tokenstream::TokenTree::span),
103103
};
104104

105105
result.push(TokenTree::MetaVarDecl(span, ident, None));
@@ -134,9 +134,9 @@ fn maybe_emit_macro_metavar_expr_feature(features: &Features, sess: &ParseSess,
134134
/// - `parsing_patterns`: same as [parse].
135135
/// - `sess`: the parsing session. Any errors will be emitted to this session.
136136
/// - `features`: language features so we can do feature gating.
137-
fn parse_tree(
138-
tree: tokenstream::TokenTree,
139-
outer_trees: &mut impl Iterator<Item = tokenstream::TokenTree>,
137+
fn parse_tree<'a>(
138+
tree: &'a tokenstream::TokenTree,
139+
outer_trees: &mut impl Iterator<Item = &'a tokenstream::TokenTree>,
140140
parsing_patterns: bool,
141141
sess: &ParseSess,
142142
node_id: NodeId,
@@ -146,21 +146,21 @@ fn parse_tree(
146146
// Depending on what `tree` is, we could be parsing different parts of a macro
147147
match tree {
148148
// `tree` is a `$` token. Look at the next token in `trees`
149-
tokenstream::TokenTree::Token(Token { kind: token::Dollar, span }, _) => {
149+
&tokenstream::TokenTree::Token(Token { kind: token::Dollar, span }, _) => {
150150
// FIXME: Handle `Invisible`-delimited groups in a more systematic way
151151
// during parsing.
152152
let mut next = outer_trees.next();
153-
let mut trees: Box<dyn Iterator<Item = tokenstream::TokenTree>>;
153+
let mut trees: Box<dyn Iterator<Item = &tokenstream::TokenTree>>;
154154
if let Some(tokenstream::TokenTree::Delimited(_, Delimiter::Invisible, tts)) = next {
155-
trees = Box::new(tts.into_trees());
155+
trees = Box::new(tts.trees());
156156
next = trees.next();
157157
} else {
158158
trees = Box::new(outer_trees);
159159
}
160160

161161
match next {
162162
// `tree` is followed by a delimited set of token trees.
163-
Some(tokenstream::TokenTree::Delimited(delim_span, delim, tts)) => {
163+
Some(&tokenstream::TokenTree::Delimited(delim_span, delim, ref tts)) => {
164164
if parsing_patterns {
165165
if delim != Delimiter::Parenthesis {
166166
span_dollar_dollar_or_metavar_in_the_lhs_err(
@@ -228,7 +228,7 @@ fn parse_tree(
228228
}
229229

230230
// `tree` is followed by another `$`. This is an escaped `$`.
231-
Some(tokenstream::TokenTree::Token(Token { kind: token::Dollar, span }, _)) => {
231+
Some(&tokenstream::TokenTree::Token(Token { kind: token::Dollar, span }, _)) => {
232232
if parsing_patterns {
233233
span_dollar_dollar_or_metavar_in_the_lhs_err(
234234
sess,
@@ -256,11 +256,11 @@ fn parse_tree(
256256
}
257257

258258
// `tree` is an arbitrary token. Keep it.
259-
tokenstream::TokenTree::Token(token, _) => TokenTree::Token(token),
259+
tokenstream::TokenTree::Token(token, _) => TokenTree::Token(token.clone()),
260260

261261
// `tree` is the beginning of a delimited set of tokens (e.g., `(` or `{`). We need to
262262
// descend into the delimited set and further parse it.
263-
tokenstream::TokenTree::Delimited(span, delim, tts) => TokenTree::Delimited(
263+
&tokenstream::TokenTree::Delimited(span, delim, ref tts) => TokenTree::Delimited(
264264
span,
265265
Delimited {
266266
delim,
@@ -286,16 +286,16 @@ fn kleene_op(token: &Token) -> Option<KleeneOp> {
286286
/// - Ok(Ok((op, span))) if the next token tree is a KleeneOp
287287
/// - Ok(Err(tok, span)) if the next token tree is a token but not a KleeneOp
288288
/// - Err(span) if the next token tree is not a token
289-
fn parse_kleene_op(
290-
input: &mut impl Iterator<Item = tokenstream::TokenTree>,
289+
fn parse_kleene_op<'a>(
290+
input: &mut impl Iterator<Item = &'a tokenstream::TokenTree>,
291291
span: Span,
292292
) -> Result<Result<(KleeneOp, Span), Token>, Span> {
293293
match input.next() {
294294
Some(tokenstream::TokenTree::Token(token, _)) => match kleene_op(&token) {
295295
Some(op) => Ok(Ok((op, token.span))),
296-
None => Ok(Err(token)),
296+
None => Ok(Err(token.clone())),
297297
},
298-
tree => Err(tree.as_ref().map_or(span, tokenstream::TokenTree::span)),
298+
tree => Err(tree.map_or(span, tokenstream::TokenTree::span)),
299299
}
300300
}
301301

@@ -311,8 +311,8 @@ fn parse_kleene_op(
311311
/// session `sess`. If the next one (or possibly two) tokens in `input` correspond to a Kleene
312312
/// operator and separator, then a tuple with `(separator, KleeneOp)` is returned. Otherwise, an
313313
/// error with the appropriate span is emitted to `sess` and a dummy value is returned.
314-
fn parse_sep_and_kleene_op(
315-
input: &mut impl Iterator<Item = tokenstream::TokenTree>,
314+
fn parse_sep_and_kleene_op<'a>(
315+
input: &mut impl Iterator<Item = &'a tokenstream::TokenTree>,
316316
span: Span,
317317
sess: &ParseSess,
318318
) -> (Option<Token>, KleeneToken) {

0 commit comments

Comments
 (0)