Use Token::uninterpolate
in couple more places matching on (Nt)Ident
This commit is contained in:
parent
5d7f67d3b1
commit
9be233cbfe
@ -441,7 +441,7 @@ impl MetaItem {
|
|||||||
I: Iterator<Item = TokenTree>,
|
I: Iterator<Item = TokenTree>,
|
||||||
{
|
{
|
||||||
// FIXME: Share code with `parse_path`.
|
// FIXME: Share code with `parse_path`.
|
||||||
let path = match tokens.next() {
|
let path = match tokens.next().map(TokenTree::uninterpolate) {
|
||||||
Some(TokenTree::Token(Token { kind: kind @ token::Ident(..), span }))
|
Some(TokenTree::Token(Token { kind: kind @ token::Ident(..), span }))
|
||||||
| Some(TokenTree::Token(Token { kind: kind @ token::ModSep, span })) => 'arm: {
|
| Some(TokenTree::Token(Token { kind: kind @ token::ModSep, span })) => 'arm: {
|
||||||
let mut segments = if let token::Ident(name, _) = kind {
|
let mut segments = if let token::Ident(name, _) = kind {
|
||||||
@ -457,7 +457,7 @@ impl MetaItem {
|
|||||||
};
|
};
|
||||||
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()
|
tokens.next().map(TokenTree::uninterpolate)
|
||||||
{
|
{
|
||||||
segments.push(PathSegment::from_ident(Ident::new(name, span)));
|
segments.push(PathSegment::from_ident(Ident::new(name, span)));
|
||||||
} else {
|
} else {
|
||||||
@ -474,7 +474,6 @@ impl MetaItem {
|
|||||||
Path { span, segments }
|
Path { span, segments }
|
||||||
}
|
}
|
||||||
Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. })) => match *nt {
|
Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. })) => match *nt {
|
||||||
token::Nonterminal::NtIdent(ident, _) => Path::from_ident(ident),
|
|
||||||
token::Nonterminal::NtMeta(ref item) => return item.meta(item.path.span),
|
token::Nonterminal::NtMeta(ref item) => return item.meta(item.path.span),
|
||||||
token::Nonterminal::NtPath(ref path) => path.clone(),
|
token::Nonterminal::NtPath(ref path) => path.clone(),
|
||||||
_ => return None,
|
_ => return None,
|
||||||
|
@ -357,7 +357,7 @@ impl Token {
|
|||||||
|
|
||||||
/// Returns `true` if the token can appear at the start of an expression.
|
/// Returns `true` if the token can appear at the start of an expression.
|
||||||
pub fn can_begin_expr(&self) -> bool {
|
pub fn can_begin_expr(&self) -> bool {
|
||||||
match self.kind {
|
match self.uninterpolate().kind {
|
||||||
Ident(name, is_raw) =>
|
Ident(name, is_raw) =>
|
||||||
ident_can_begin_expr(name, self.span, is_raw), // value name or keyword
|
ident_can_begin_expr(name, self.span, is_raw), // value name or keyword
|
||||||
OpenDelim(..) | // tuple, array or block
|
OpenDelim(..) | // tuple, array or block
|
||||||
@ -375,12 +375,10 @@ impl Token {
|
|||||||
Lifetime(..) | // labeled loop
|
Lifetime(..) | // labeled loop
|
||||||
Pound => true, // expression attributes
|
Pound => true, // expression attributes
|
||||||
Interpolated(ref nt) => match **nt {
|
Interpolated(ref nt) => match **nt {
|
||||||
NtIdent(ident, is_raw) => ident_can_begin_expr(ident.name, ident.span, is_raw),
|
|
||||||
NtLiteral(..) |
|
NtLiteral(..) |
|
||||||
NtExpr(..) |
|
NtExpr(..) |
|
||||||
NtBlock(..) |
|
NtBlock(..) |
|
||||||
NtPath(..) |
|
NtPath(..) => true,
|
||||||
NtLifetime(..) => true,
|
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
_ => false,
|
_ => false,
|
||||||
@ -389,7 +387,7 @@ impl Token {
|
|||||||
|
|
||||||
/// Returns `true` if the token can appear at the start of a type.
|
/// Returns `true` if the token can appear at the start of a type.
|
||||||
pub fn can_begin_type(&self) -> bool {
|
pub fn can_begin_type(&self) -> bool {
|
||||||
match self.kind {
|
match self.uninterpolate().kind {
|
||||||
Ident(name, is_raw) =>
|
Ident(name, is_raw) =>
|
||||||
ident_can_begin_type(name, self.span, is_raw), // type name or keyword
|
ident_can_begin_type(name, self.span, is_raw), // type name or keyword
|
||||||
OpenDelim(Paren) | // tuple
|
OpenDelim(Paren) | // tuple
|
||||||
@ -403,8 +401,7 @@ impl Token {
|
|||||||
Lt | BinOp(Shl) | // associated path
|
Lt | BinOp(Shl) | // associated path
|
||||||
ModSep => true, // global path
|
ModSep => true, // global path
|
||||||
Interpolated(ref nt) => match **nt {
|
Interpolated(ref nt) => match **nt {
|
||||||
NtIdent(ident, is_raw) => ident_can_begin_type(ident.name, ident.span, is_raw),
|
NtTy(..) | NtPath(..) => true,
|
||||||
NtTy(..) | NtPath(..) | NtLifetime(..) => true,
|
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
_ => false,
|
_ => false,
|
||||||
@ -445,11 +442,10 @@ impl Token {
|
|||||||
///
|
///
|
||||||
/// Keep this in sync with `Lit::from_token`.
|
/// Keep this in sync with `Lit::from_token`.
|
||||||
pub fn can_begin_literal_or_bool(&self) -> bool {
|
pub fn can_begin_literal_or_bool(&self) -> bool {
|
||||||
match self.kind {
|
match self.uninterpolate().kind {
|
||||||
Literal(..) | BinOp(Minus) => true,
|
Literal(..) | BinOp(Minus) => true,
|
||||||
Ident(name, false) if name.is_bool_lit() => true,
|
Ident(name, false) if name.is_bool_lit() => true,
|
||||||
Interpolated(ref nt) => match &**nt {
|
Interpolated(ref nt) => match &**nt {
|
||||||
NtIdent(ident, false) if ident.name.is_bool_lit() => true,
|
|
||||||
NtExpr(e) | NtLiteral(e) => matches!(e.kind, ast::ExprKind::Lit(_)),
|
NtExpr(e) | NtLiteral(e) => matches!(e.kind, ast::ExprKind::Lit(_)),
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
@ -475,24 +471,18 @@ impl Token {
|
|||||||
|
|
||||||
/// Returns an identifier if this token is an identifier.
|
/// Returns an identifier if this token is an identifier.
|
||||||
pub fn ident(&self) -> Option<(ast::Ident, /* is_raw */ bool)> {
|
pub fn ident(&self) -> Option<(ast::Ident, /* is_raw */ bool)> {
|
||||||
match self.kind {
|
let token = self.uninterpolate();
|
||||||
Ident(name, is_raw) => Some((ast::Ident::new(name, self.span), is_raw)),
|
match token.kind {
|
||||||
Interpolated(ref nt) => match **nt {
|
Ident(name, is_raw) => Some((ast::Ident::new(name, token.span), is_raw)),
|
||||||
NtIdent(ident, is_raw) => Some((ident, is_raw)),
|
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a lifetime identifier if this token is a lifetime.
|
/// Returns a lifetime identifier if this token is a lifetime.
|
||||||
pub fn lifetime(&self) -> Option<ast::Ident> {
|
pub fn lifetime(&self) -> Option<ast::Ident> {
|
||||||
match self.kind {
|
let token = self.uninterpolate();
|
||||||
Lifetime(name) => Some(ast::Ident::new(name, self.span)),
|
match token.kind {
|
||||||
Interpolated(ref nt) => match **nt {
|
Lifetime(name) => Some(ast::Ident::new(name, token.span)),
|
||||||
NtLifetime(ident) => Some(ident),
|
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,6 +116,13 @@ impl TokenTree {
|
|||||||
pub fn close_tt(span: DelimSpan, delim: DelimToken) -> TokenTree {
|
pub fn close_tt(span: DelimSpan, delim: DelimToken) -> TokenTree {
|
||||||
TokenTree::token(token::CloseDelim(delim), span.close)
|
TokenTree::token(token::CloseDelim(delim), span.close)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn uninterpolate(self) -> TokenTree {
|
||||||
|
match self {
|
||||||
|
TokenTree::Token(token) => TokenTree::Token(token.uninterpolate().into_owned()),
|
||||||
|
tt => tt,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<CTX> HashStable<CTX> for TokenStream
|
impl<CTX> HashStable<CTX> for TokenStream
|
||||||
|
@ -191,23 +191,16 @@ impl Lit {
|
|||||||
///
|
///
|
||||||
/// Keep this in sync with `Token::can_begin_literal_or_bool`.
|
/// Keep this in sync with `Token::can_begin_literal_or_bool`.
|
||||||
pub fn from_token(token: &Token) -> Result<Lit, LitError> {
|
pub fn from_token(token: &Token) -> Result<Lit, LitError> {
|
||||||
let lit = match token.kind {
|
let lit = match token.uninterpolate().kind {
|
||||||
token::Ident(name, false) if name.is_bool_lit() => {
|
token::Ident(name, false) if name.is_bool_lit() => {
|
||||||
token::Lit::new(token::Bool, name, None)
|
token::Lit::new(token::Bool, name, None)
|
||||||
}
|
}
|
||||||
token::Literal(lit) => lit,
|
token::Literal(lit) => lit,
|
||||||
token::Interpolated(ref nt) => {
|
token::Interpolated(ref nt) => {
|
||||||
match &**nt {
|
if let token::NtExpr(expr) | token::NtLiteral(expr) = &**nt {
|
||||||
token::NtIdent(ident, false) if ident.name.is_bool_lit() => {
|
if let ast::ExprKind::Lit(lit) = &expr.kind {
|
||||||
let lit = token::Lit::new(token::Bool, ident.name, None);
|
return Ok(lit.clone());
|
||||||
return Lit::from_lit_token(lit, ident.span);
|
|
||||||
}
|
}
|
||||||
token::NtExpr(expr) | token::NtLiteral(expr) => {
|
|
||||||
if let ast::ExprKind::Lit(lit) = &expr.kind {
|
|
||||||
return Ok(lit.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
return Err(LitError::NotLiteral);
|
return Err(LitError::NotLiteral);
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,6 @@ macro_rules! maybe_whole_expr {
|
|||||||
AttrVec::new(),
|
AttrVec::new(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
// N.B., `NtIdent(ident)` is normalized to `Ident` in `fn bump`.
|
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -482,7 +481,7 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_mistaken_not_ident_negation(&self) -> bool {
|
fn is_mistaken_not_ident_negation(&self) -> bool {
|
||||||
let token_cannot_continue_expr = |t: &Token| match t.kind {
|
let token_cannot_continue_expr = |t: &Token| match t.uninterpolate().kind {
|
||||||
// These tokens can start an expression after `!`, but
|
// These tokens can start an expression after `!`, but
|
||||||
// can't continue an expression after an ident
|
// can't continue an expression after an ident
|
||||||
token::Ident(name, is_raw) => token::ident_can_begin_expr(name, t.span, is_raw),
|
token::Ident(name, is_raw) => token::ident_can_begin_expr(name, t.span, is_raw),
|
||||||
|
@ -1544,6 +1544,8 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
let is_name_required = match self.token.kind {
|
let is_name_required = match self.token.kind {
|
||||||
token::DotDotDot => false,
|
token::DotDotDot => false,
|
||||||
|
// FIXME: Consider using interpolated token for this edition check,
|
||||||
|
// it should match the intent of edition hygiene better.
|
||||||
_ => req_name(self.token.uninterpolate().span.edition()),
|
_ => req_name(self.token.uninterpolate().span.edition()),
|
||||||
};
|
};
|
||||||
let (pat, ty) = if is_name_required || self.is_named_param() {
|
let (pat, ty) = if is_name_required || self.is_named_param() {
|
||||||
|
@ -151,7 +151,7 @@ impl<'a> Parser<'a> {
|
|||||||
/// Note that there are more tokens such as `@` for which we know that the `|`
|
/// Note that there are more tokens such as `@` for which we know that the `|`
|
||||||
/// is an illegal parse. However, the user's intent is less clear in that case.
|
/// is an illegal parse. However, the user's intent is less clear in that case.
|
||||||
fn recover_trailing_vert(&mut self, lo: Option<Span>) -> bool {
|
fn recover_trailing_vert(&mut self, lo: Option<Span>) -> bool {
|
||||||
let is_end_ahead = self.look_ahead(1, |token| match &token.kind {
|
let is_end_ahead = self.look_ahead(1, |token| match &token.uninterpolate().kind {
|
||||||
token::FatArrow // e.g. `a | => 0,`.
|
token::FatArrow // e.g. `a | => 0,`.
|
||||||
| token::Ident(kw::If, false) // e.g. `a | if expr`.
|
| token::Ident(kw::If, false) // e.g. `a | if expr`.
|
||||||
| token::Eq // e.g. `let a | = 0`.
|
| token::Eq // e.g. `let a | = 0`.
|
||||||
|
Loading…
Reference in New Issue
Block a user