Make TokenTree::uninterpolate
take &self
and return a Cow
.
Making it similar to `Token::uninterpolate`. This avoids some more token tree cloning.
This commit is contained in:
parent
103bd4a820
commit
55a732461d
@ -290,12 +290,12 @@ impl MetaItem {
|
|||||||
I: Iterator<Item = &'a TokenTree>,
|
I: Iterator<Item = &'a TokenTree>,
|
||||||
{
|
{
|
||||||
// FIXME: Share code with `parse_path`.
|
// FIXME: Share code with `parse_path`.
|
||||||
let path = match tokens.next().map(|tt| TokenTree::uninterpolate(tt.clone())) {
|
let path = match tokens.next().map(|tt| TokenTree::uninterpolate(tt)).as_deref() {
|
||||||
Some(TokenTree::Token(
|
Some(&TokenTree::Token(
|
||||||
Token { kind: kind @ (token::Ident(..) | token::ModSep), span },
|
Token { kind: ref kind @ (token::Ident(..) | token::ModSep), span },
|
||||||
_,
|
_,
|
||||||
)) => 'arm: {
|
)) => 'arm: {
|
||||||
let mut segments = if let token::Ident(name, _) = kind {
|
let mut segments = if let &token::Ident(name, _) = kind {
|
||||||
if let Some(TokenTree::Token(Token { kind: token::ModSep, .. }, _)) =
|
if let Some(TokenTree::Token(Token { kind: token::ModSep, .. }, _)) =
|
||||||
tokens.peek()
|
tokens.peek()
|
||||||
{
|
{
|
||||||
@ -308,8 +308,8 @@ impl MetaItem {
|
|||||||
thin_vec![PathSegment::path_root(span)]
|
thin_vec![PathSegment::path_root(span)]
|
||||||
};
|
};
|
||||||
loop {
|
loop {
|
||||||
if let Some(TokenTree::Token(Token { kind: token::Ident(name, _), span }, _)) =
|
if let Some(&TokenTree::Token(Token { kind: token::Ident(name, _), span }, _)) =
|
||||||
tokens.next().map(|tt| TokenTree::uninterpolate(tt.clone()))
|
tokens.next().map(|tt| TokenTree::uninterpolate(tt)).as_deref()
|
||||||
{
|
{
|
||||||
segments.push(PathSegment::from_ident(Ident::new(name, span)));
|
segments.push(PathSegment::from_ident(Ident::new(name, span)));
|
||||||
} else {
|
} else {
|
||||||
@ -326,7 +326,7 @@ impl MetaItem {
|
|||||||
let span = span.with_hi(segments.last().unwrap().ident.span.hi());
|
let span = span.with_hi(segments.last().unwrap().ident.span.hi());
|
||||||
Path { span, segments, tokens: None }
|
Path { span, segments, tokens: None }
|
||||||
}
|
}
|
||||||
Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match &*nt {
|
Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match &**nt {
|
||||||
token::Nonterminal::NtMeta(item) => return item.meta(item.path.span),
|
token::Nonterminal::NtMeta(item) => return item.meta(item.path.span),
|
||||||
token::Nonterminal::NtPath(path) => (**path).clone(),
|
token::Nonterminal::NtPath(path) => (**path).clone(),
|
||||||
_ => return None,
|
_ => return None,
|
||||||
|
@ -25,6 +25,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
|
|||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::{fmt, iter, mem};
|
use std::{fmt, iter, mem};
|
||||||
|
|
||||||
/// When the main Rust parser encounters a syntax-extension invocation, it
|
/// When the main Rust parser encounters a syntax-extension invocation, it
|
||||||
@ -98,12 +99,13 @@ impl TokenTree {
|
|||||||
TokenTree::Token(Token::new(kind, span), Spacing::Joint)
|
TokenTree::Token(Token::new(kind, span), Spacing::Joint)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uninterpolate(self) -> TokenTree {
|
pub fn uninterpolate(&self) -> Cow<'_, TokenTree> {
|
||||||
match self {
|
match self {
|
||||||
TokenTree::Token(token, spacing) => {
|
TokenTree::Token(token, spacing) => match token.uninterpolate() {
|
||||||
TokenTree::Token(token.uninterpolate().into_owned(), spacing)
|
Cow::Owned(token) => Cow::Owned(TokenTree::Token(token, *spacing)),
|
||||||
}
|
Cow::Borrowed(_) => Cow::Borrowed(self),
|
||||||
tt => tt,
|
},
|
||||||
|
_ => Cow::Borrowed(self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user