Skip to content

Commit 55a7324

Browse files
committed
Make TokenTree::uninterpolate take &self and return a Cow.
Making it similar to `Token::uninterpolate`. This avoids some more token tree cloning.
1 parent 103bd4a commit 55a7324

File tree

2 files changed

+14
-12
lines changed

2 files changed

+14
-12
lines changed

compiler/rustc_ast/src/attr/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -290,12 +290,12 @@ impl MetaItem {
290290
I: Iterator<Item = &'a TokenTree>,
291291
{
292292
// FIXME: Share code with `parse_path`.
293-
let path = match tokens.next().map(|tt| TokenTree::uninterpolate(tt.clone())) {
294-
Some(TokenTree::Token(
295-
Token { kind: kind @ (token::Ident(..) | token::ModSep), span },
293+
let path = match tokens.next().map(|tt| TokenTree::uninterpolate(tt)).as_deref() {
294+
Some(&TokenTree::Token(
295+
Token { kind: ref kind @ (token::Ident(..) | token::ModSep), span },
296296
_,
297297
)) => 'arm: {
298-
let mut segments = if let token::Ident(name, _) = kind {
298+
let mut segments = if let &token::Ident(name, _) = kind {
299299
if let Some(TokenTree::Token(Token { kind: token::ModSep, .. }, _)) =
300300
tokens.peek()
301301
{
@@ -308,8 +308,8 @@ impl MetaItem {
308308
thin_vec![PathSegment::path_root(span)]
309309
};
310310
loop {
311-
if let Some(TokenTree::Token(Token { kind: token::Ident(name, _), span }, _)) =
312-
tokens.next().map(|tt| TokenTree::uninterpolate(tt.clone()))
311+
if let Some(&TokenTree::Token(Token { kind: token::Ident(name, _), span }, _)) =
312+
tokens.next().map(|tt| TokenTree::uninterpolate(tt)).as_deref()
313313
{
314314
segments.push(PathSegment::from_ident(Ident::new(name, span)));
315315
} else {
@@ -326,7 +326,7 @@ impl MetaItem {
326326
let span = span.with_hi(segments.last().unwrap().ident.span.hi());
327327
Path { span, segments, tokens: None }
328328
}
329-
Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match &*nt {
329+
Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match &**nt {
330330
token::Nonterminal::NtMeta(item) => return item.meta(item.path.span),
331331
token::Nonterminal::NtPath(path) => (**path).clone(),
332332
_ => return None,

compiler/rustc_ast/src/tokenstream.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
2525
use rustc_span::{Span, DUMMY_SP};
2626
use smallvec::{smallvec, SmallVec};
2727

28+
use std::borrow::Cow;
2829
use std::{fmt, iter, mem};
2930

3031
/// When the main Rust parser encounters a syntax-extension invocation, it
@@ -98,12 +99,13 @@ impl TokenTree {
9899
TokenTree::Token(Token::new(kind, span), Spacing::Joint)
99100
}
100101

101-
pub fn uninterpolate(self) -> TokenTree {
102+
pub fn uninterpolate(&self) -> Cow<'_, TokenTree> {
102103
match self {
103-
TokenTree::Token(token, spacing) => {
104-
TokenTree::Token(token.uninterpolate().into_owned(), spacing)
105-
}
106-
tt => tt,
104+
TokenTree::Token(token, spacing) => match token.uninterpolate() {
105+
Cow::Owned(token) => Cow::Owned(TokenTree::Token(token, *spacing)),
106+
Cow::Borrowed(_) => Cow::Borrowed(self),
107+
},
108+
_ => Cow::Borrowed(self),
107109
}
108110
}
109111
}

0 commit comments

Comments
 (0)