From 9be233cbfe134f032ed2d50f7cc66e901bbe3f6f Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 7 Mar 2020 15:58:27 +0300 Subject: [PATCH] Use `Token::uninterpolate` in couple more places matching on `(Nt)Ident` --- src/librustc_ast/attr/mod.rs | 5 ++--- src/librustc_ast/token.rs | 32 +++++++++++-------------------- src/librustc_ast/tokenstream.rs | 7 +++++++ src/librustc_ast/util/literal.rs | 15 ++++----------- src/librustc_parse/parser/expr.rs | 3 +-- src/librustc_parse/parser/item.rs | 2 ++ src/librustc_parse/parser/pat.rs | 2 +- 7 files changed, 28 insertions(+), 38 deletions(-) diff --git a/src/librustc_ast/attr/mod.rs b/src/librustc_ast/attr/mod.rs index 280994116c0..52a59e82ae2 100644 --- a/src/librustc_ast/attr/mod.rs +++ b/src/librustc_ast/attr/mod.rs @@ -441,7 +441,7 @@ impl MetaItem { I: Iterator, { // 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::ModSep, span })) => 'arm: { let mut segments = if let token::Ident(name, _) = kind { @@ -457,7 +457,7 @@ impl MetaItem { }; loop { 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))); } else { @@ -474,7 +474,6 @@ impl MetaItem { Path { span, segments } } 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::NtPath(ref path) => path.clone(), _ => return None, diff --git a/src/librustc_ast/token.rs b/src/librustc_ast/token.rs index b80694ab6de..b022d969dec 100644 --- a/src/librustc_ast/token.rs +++ b/src/librustc_ast/token.rs @@ -357,7 +357,7 @@ impl Token { /// Returns `true` if the token can appear at the start of an expression. pub fn can_begin_expr(&self) -> bool { - match self.kind { + match self.uninterpolate().kind { Ident(name, is_raw) => ident_can_begin_expr(name, self.span, is_raw), // value name or keyword OpenDelim(..) | // tuple, array or block @@ -375,12 +375,10 @@ impl Token { Lifetime(..) | // labeled loop Pound => true, // expression attributes Interpolated(ref nt) => match **nt { - NtIdent(ident, is_raw) => ident_can_begin_expr(ident.name, ident.span, is_raw), NtLiteral(..) | NtExpr(..) | NtBlock(..) | - NtPath(..) | - NtLifetime(..) => true, + NtPath(..) => true, _ => false, }, _ => false, @@ -389,7 +387,7 @@ impl Token { /// Returns `true` if the token can appear at the start of a type. pub fn can_begin_type(&self) -> bool { - match self.kind { + match self.uninterpolate().kind { Ident(name, is_raw) => ident_can_begin_type(name, self.span, is_raw), // type name or keyword OpenDelim(Paren) | // tuple @@ -403,8 +401,7 @@ impl Token { Lt | BinOp(Shl) | // associated path ModSep => true, // global path Interpolated(ref nt) => match **nt { - NtIdent(ident, is_raw) => ident_can_begin_type(ident.name, ident.span, is_raw), - NtTy(..) | NtPath(..) | NtLifetime(..) => true, + NtTy(..) | NtPath(..) => true, _ => false, }, _ => false, @@ -445,11 +442,10 @@ impl Token { /// /// Keep this in sync with `Lit::from_token`. pub fn can_begin_literal_or_bool(&self) -> bool { - match self.kind { + match self.uninterpolate().kind { Literal(..) | BinOp(Minus) => true, Ident(name, false) if name.is_bool_lit() => true, 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(_)), _ => false, }, @@ -475,24 +471,18 @@ impl Token { /// Returns an identifier if this token is an identifier. pub fn ident(&self) -> Option<(ast::Ident, /* is_raw */ bool)> { - match self.kind { - Ident(name, is_raw) => Some((ast::Ident::new(name, self.span), is_raw)), - Interpolated(ref nt) => match **nt { - NtIdent(ident, is_raw) => Some((ident, is_raw)), - _ => None, - }, + let token = self.uninterpolate(); + match token.kind { + Ident(name, is_raw) => Some((ast::Ident::new(name, token.span), is_raw)), _ => None, } } /// Returns a lifetime identifier if this token is a lifetime. pub fn lifetime(&self) -> Option { - match self.kind { - Lifetime(name) => Some(ast::Ident::new(name, self.span)), - Interpolated(ref nt) => match **nt { - NtLifetime(ident) => Some(ident), - _ => None, - }, + let token = self.uninterpolate(); + match token.kind { + Lifetime(name) => Some(ast::Ident::new(name, token.span)), _ => None, } } diff --git a/src/librustc_ast/tokenstream.rs b/src/librustc_ast/tokenstream.rs index 03e8fff247b..916a5ff6f46 100644 --- a/src/librustc_ast/tokenstream.rs +++ b/src/librustc_ast/tokenstream.rs @@ -116,6 +116,13 @@ impl TokenTree { pub fn close_tt(span: DelimSpan, delim: DelimToken) -> TokenTree { 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 HashStable for TokenStream diff --git a/src/librustc_ast/util/literal.rs b/src/librustc_ast/util/literal.rs index ecf17efc4e0..d1757394f3a 100644 --- a/src/librustc_ast/util/literal.rs +++ b/src/librustc_ast/util/literal.rs @@ -191,23 +191,16 @@ impl Lit { /// /// Keep this in sync with `Token::can_begin_literal_or_bool`. pub fn from_token(token: &Token) -> Result { - let lit = match token.kind { + let lit = match token.uninterpolate().kind { token::Ident(name, false) if name.is_bool_lit() => { token::Lit::new(token::Bool, name, None) } token::Literal(lit) => lit, token::Interpolated(ref nt) => { - match &**nt { - token::NtIdent(ident, false) if ident.name.is_bool_lit() => { - let lit = token::Lit::new(token::Bool, ident.name, None); - return Lit::from_lit_token(lit, ident.span); + if let token::NtExpr(expr) | token::NtLiteral(expr) = &**nt { + if let ast::ExprKind::Lit(lit) = &expr.kind { + return Ok(lit.clone()); } - token::NtExpr(expr) | token::NtLiteral(expr) => { - if let ast::ExprKind::Lit(lit) = &expr.kind { - return Ok(lit.clone()); - } - } - _ => {} } return Err(LitError::NotLiteral); } diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index f7cfb028a7a..d28b9cd9682 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -50,7 +50,6 @@ macro_rules! maybe_whole_expr { 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 { - 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 // can't continue an expression after an ident token::Ident(name, is_raw) => token::ident_can_begin_expr(name, t.span, is_raw), diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 08d71f03976..bf612bfc0e4 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -1544,6 +1544,8 @@ impl<'a> Parser<'a> { let is_name_required = match self.token.kind { 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()), }; let (pat, ty) = if is_name_required || self.is_named_param() { diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs index 4c041fd669d..f52a91ff598 100644 --- a/src/librustc_parse/parser/pat.rs +++ b/src/librustc_parse/parser/pat.rs @@ -151,7 +151,7 @@ impl<'a> Parser<'a> { /// 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. fn recover_trailing_vert(&mut self, lo: Option) -> 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::Ident(kw::If, false) // e.g. `a | if expr`. | token::Eq // e.g. `let a | = 0`.