1
Fork 0

Make lifetime nonterminals closer to identifier nonterminals

This commit is contained in:
Vadim Petrochenkov 2018-03-24 19:49:50 +03:00
parent b3b5ef186c
commit bfaf4180ae
5 changed files with 47 additions and 47 deletions

View file

@ -365,7 +365,7 @@ pub fn parse_failure_msg(tok: Token) -> String {
fn token_name_eq(t1: &Token, t2: &Token) -> bool { fn token_name_eq(t1: &Token, t2: &Token) -> bool {
if let (Some((id1, is_raw1)), Some((id2, is_raw2))) = (t1.ident(), t2.ident()) { if let (Some((id1, is_raw1)), Some((id2, is_raw2))) = (t1.ident(), t2.ident()) {
id1.name == id2.name && is_raw1 == is_raw2 id1.name == id2.name && is_raw1 == is_raw2
} else if let (&token::Lifetime(id1), &token::Lifetime(id2)) = (t1, t2) { } else if let (Some(id1), Some(id2)) = (t1.lifetime(), t2.lifetime()) {
id1.name == id2.name id1.name == id2.name
} else { } else {
*t1 == *t2 *t1 == *t2
@ -835,7 +835,7 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal {
"path" => token::NtPath(panictry!(p.parse_path_common(PathStyle::Type, false))), "path" => token::NtPath(panictry!(p.parse_path_common(PathStyle::Type, false))),
"meta" => token::NtMeta(panictry!(p.parse_meta_item())), "meta" => token::NtMeta(panictry!(p.parse_meta_item())),
"vis" => token::NtVis(panictry!(p.parse_visibility(true))), "vis" => token::NtVis(panictry!(p.parse_visibility(true))),
"lifetime" => token::NtLifetime(p.expect_lifetime()), "lifetime" => token::NtLifetime(p.expect_lifetime().ident),
// this is not supposed to happen, since it has been checked // this is not supposed to happen, since it has been checked
// when compiling the macro. // when compiling the macro.
_ => p.span_bug(sp, "invalid fragment specifier"), _ => p.span_bug(sp, "invalid fragment specifier"),

View file

@ -633,7 +633,8 @@ pub fn noop_fold_interpolated<T: Folder>(nt: token::Nonterminal, fld: &mut T)
token::NtPat(pat) => token::NtPat(fld.fold_pat(pat)), token::NtPat(pat) => token::NtPat(fld.fold_pat(pat)),
token::NtExpr(expr) => token::NtExpr(fld.fold_expr(expr)), token::NtExpr(expr) => token::NtExpr(fld.fold_expr(expr)),
token::NtTy(ty) => token::NtTy(fld.fold_ty(ty)), token::NtTy(ty) => token::NtTy(fld.fold_ty(ty)),
token::NtIdent(id, is_raw) => token::NtIdent(fld.fold_ident(id), is_raw), token::NtIdent(ident, is_raw) => token::NtIdent(fld.fold_ident(ident), is_raw),
token::NtLifetime(ident) => token::NtLifetime(fld.fold_ident(ident)),
token::NtMeta(meta) => token::NtMeta(fld.fold_meta_item(meta)), token::NtMeta(meta) => token::NtMeta(fld.fold_meta_item(meta)),
token::NtPath(path) => token::NtPath(fld.fold_path(path)), token::NtPath(path) => token::NtPath(fld.fold_path(path)),
token::NtTT(tt) => token::NtTT(fld.fold_tt(tt)), token::NtTT(tt) => token::NtTT(fld.fold_tt(tt)),
@ -649,7 +650,6 @@ pub fn noop_fold_interpolated<T: Folder>(nt: token::Nonterminal, fld: &mut T)
token::NtWhereClause(fld.fold_where_clause(where_clause)), token::NtWhereClause(fld.fold_where_clause(where_clause)),
token::NtArg(arg) => token::NtArg(fld.fold_arg(arg)), token::NtArg(arg) => token::NtArg(fld.fold_arg(arg)),
token::NtVis(vis) => token::NtVis(fld.fold_vis(vis)), token::NtVis(vis) => token::NtVis(fld.fold_vis(vis)),
token::NtLifetime(lifetime) => token::NtLifetime(fld.fold_lifetime(lifetime)),
token::NtForeignItem(ni) => token::NtForeignItem(ni) =>
token::NtForeignItem(fld.fold_foreign_item(ni) token::NtForeignItem(fld.fold_foreign_item(ni)
// see reasoning above // see reasoning above

View file

@ -2048,18 +2048,20 @@ impl<'a> Parser<'a> {
/// Parse single lifetime 'a or panic. /// Parse single lifetime 'a or panic.
pub fn expect_lifetime(&mut self) -> Lifetime { pub fn expect_lifetime(&mut self) -> Lifetime {
if let Some(lifetime) = self.token.lifetime2(self.span) { if let Some(ident) = self.token.lifetime() {
let span = self.span;
self.bump(); self.bump();
lifetime Lifetime { ident: Ident::new(ident.name, span), id: ast::DUMMY_NODE_ID }
} else { } else {
self.span_bug(self.span, "not a lifetime") self.span_bug(self.span, "not a lifetime")
} }
} }
fn eat_label(&mut self) -> Option<Label> { fn eat_label(&mut self) -> Option<Label> {
if let Some(lifetime) = self.token.lifetime2(self.span) { if let Some(ident) = self.token.lifetime() {
let span = self.span;
self.bump(); self.bump();
Some(Label { ident: lifetime.ident }) Some(Label { ident: Ident::new(ident.name, span) })
} else { } else {
None None
} }
@ -2703,7 +2705,7 @@ impl<'a> Parser<'a> {
} }
pub fn process_potential_macro_variable(&mut self) { pub fn process_potential_macro_variable(&mut self) {
let (ident, is_raw) = match self.token { let (token, span) = match self.token {
token::Dollar if self.span.ctxt() != syntax_pos::hygiene::SyntaxContext::empty() && token::Dollar if self.span.ctxt() != syntax_pos::hygiene::SyntaxContext::empty() &&
self.look_ahead(1, |t| t.is_ident()) => { self.look_ahead(1, |t| t.is_ident()) => {
self.bump(); self.bump();
@ -2718,15 +2720,18 @@ impl<'a> Parser<'a> {
} }
token::Interpolated(ref nt) => { token::Interpolated(ref nt) => {
self.meta_var_span = Some(self.span); self.meta_var_span = Some(self.span);
// Interpolated identifier and lifetime tokens are replaced with usual identifier
// and lifetime tokens, so the former are never encountered during normal parsing.
match nt.0 { match nt.0 {
token::NtIdent(ident, is_raw) => (ident, is_raw), token::NtIdent(ident, is_raw) => (token::Ident(ident, is_raw), ident.span),
token::NtLifetime(ident) => (token::Lifetime(ident), ident.span),
_ => return, _ => return,
} }
} }
_ => return, _ => return,
}; };
self.token = token::Ident(ident, is_raw); self.token = token;
self.span = ident.span; self.span = span;
} }
/// parse a single token tree from the input. /// parse a single token tree from the input.

View file

@ -317,7 +317,8 @@ impl Token {
} }
} }
pub fn ident(&self) -> Option<(ast::Ident, bool)> { /// Returns an identifier if this token is an identifier.
pub fn ident(&self) -> Option<(ast::Ident, /* is_raw */ bool)> {
match *self { match *self {
Ident(ident, is_raw) => Some((ident, is_raw)), Ident(ident, is_raw) => Some((ident, is_raw)),
Interpolated(ref nt) => match nt.0 { Interpolated(ref nt) => match nt.0 {
@ -327,11 +328,25 @@ impl Token {
_ => None, _ => None,
} }
} }
/// Returns a lifetime identifier if this token is a lifetime.
pub fn lifetime(&self) -> Option<ast::Ident> {
match *self {
Lifetime(ident) => Some(ident),
Interpolated(ref nt) => match nt.0 {
NtLifetime(ident) => Some(ident),
_ => None,
},
_ => None,
}
}
/// Returns `true` if the token is an identifier. /// Returns `true` if the token is an identifier.
pub fn is_ident(&self) -> bool { pub fn is_ident(&self) -> bool {
self.ident().is_some() self.ident().is_some()
} }
/// Returns `true` if the token is a lifetime.
pub fn is_lifetime(&self) -> bool {
self.lifetime().is_some()
}
/// Returns `true` if the token is a documentation comment. /// Returns `true` if the token is a documentation comment.
pub fn is_doc_comment(&self) -> bool { pub fn is_doc_comment(&self) -> bool {
@ -359,26 +374,6 @@ impl Token {
false false
} }
/// Returns a lifetime with the span and a dummy id if it is a lifetime,
/// or the original lifetime if it is an interpolated lifetime, ignoring
/// the span.
pub fn lifetime2(&self, span: Span) -> Option<ast::Lifetime> {
match *self {
Lifetime(ident) => Some(ast::Lifetime { id: ast::DUMMY_NODE_ID,
ident: ast::Ident::new(ident.name, span) }),
Interpolated(ref nt) => match nt.0 {
NtLifetime(lifetime) => Some(lifetime),
_ => None,
},
_ => None,
}
}
/// Returns `true` if the token is a lifetime.
pub fn is_lifetime(&self) -> bool {
self.lifetime2(syntax_pos::DUMMY_SP).is_some()
}
/// Returns `true` if the token is either the `mut` or `const` keyword. /// Returns `true` if the token is either the `mut` or `const` keyword.
pub fn is_mutability(&self) -> bool { pub fn is_mutability(&self) -> bool {
self.is_keyword(keywords::Mut) || self.is_keyword(keywords::Mut) ||
@ -431,6 +426,14 @@ impl Token {
} }
} }
/// Returns `true` if the token is either a special identifier or a keyword.
pub fn is_reserved_ident(&self) -> bool {
match self.ident() {
Some((id, false)) => is_reserved_ident(id),
_ => false,
}
}
pub fn glue(self, joint: Token) -> Option<Token> { pub fn glue(self, joint: Token) -> Option<Token> {
Some(match self { Some(match self {
Eq => match joint { Eq => match joint {
@ -497,14 +500,6 @@ impl Token {
} }
} }
/// Returns `true` if the token is either a special identifier or a keyword.
pub fn is_reserved_ident(&self) -> bool {
match self.ident() {
Some((id, false)) => is_reserved_ident(id),
_ => false,
}
}
pub fn interpolated_to_tokenstream(&self, sess: &ParseSess, span: Span) pub fn interpolated_to_tokenstream(&self, sess: &ParseSess, span: Span)
-> TokenStream -> TokenStream
{ {
@ -542,9 +537,9 @@ impl Token {
let token = Token::Ident(ident, is_raw); let token = Token::Ident(ident, is_raw);
tokens = Some(TokenTree::Token(ident.span, token).into()); tokens = Some(TokenTree::Token(ident.span, token).into());
} }
Nonterminal::NtLifetime(lifetime) => { Nonterminal::NtLifetime(ident) => {
let token = Token::Lifetime(lifetime.ident); let token = Token::Lifetime(ident);
tokens = Some(TokenTree::Token(lifetime.ident.span, token).into()); tokens = Some(TokenTree::Token(ident.span, token).into());
} }
Nonterminal::NtTT(ref tt) => { Nonterminal::NtTT(ref tt) => {
tokens = Some(tt.clone().into()); tokens = Some(tt.clone().into());
@ -572,6 +567,7 @@ pub enum Nonterminal {
NtExpr(P<ast::Expr>), NtExpr(P<ast::Expr>),
NtTy(P<ast::Ty>), NtTy(P<ast::Ty>),
NtIdent(ast::Ident, /* is_raw */ bool), NtIdent(ast::Ident, /* is_raw */ bool),
NtLifetime(ast::Ident),
/// Stuff inside brackets for attributes /// Stuff inside brackets for attributes
NtMeta(ast::MetaItem), NtMeta(ast::MetaItem),
NtPath(ast::Path), NtPath(ast::Path),
@ -585,7 +581,6 @@ pub enum Nonterminal {
NtGenerics(ast::Generics), NtGenerics(ast::Generics),
NtWhereClause(ast::WhereClause), NtWhereClause(ast::WhereClause),
NtArg(ast::Arg), NtArg(ast::Arg),
NtLifetime(ast::Lifetime),
} }
impl fmt::Debug for Nonterminal { impl fmt::Debug for Nonterminal {

View file

@ -272,6 +272,7 @@ pub fn token_to_string(tok: &Token) -> String {
token::NtPat(ref e) => pat_to_string(e), token::NtPat(ref e) => pat_to_string(e),
token::NtIdent(e, false) => ident_to_string(e), token::NtIdent(e, false) => ident_to_string(e),
token::NtIdent(e, true) => format!("r#{}", ident_to_string(e)), token::NtIdent(e, true) => format!("r#{}", ident_to_string(e)),
token::NtLifetime(e) => ident_to_string(e),
token::NtTT(ref tree) => tt_to_string(tree.clone()), token::NtTT(ref tree) => tt_to_string(tree.clone()),
token::NtArm(ref e) => arm_to_string(e), token::NtArm(ref e) => arm_to_string(e),
token::NtImplItem(ref e) => impl_item_to_string(e), token::NtImplItem(ref e) => impl_item_to_string(e),
@ -280,7 +281,6 @@ pub fn token_to_string(tok: &Token) -> String {
token::NtWhereClause(ref e) => where_clause_to_string(e), token::NtWhereClause(ref e) => where_clause_to_string(e),
token::NtArg(ref e) => arg_to_string(e), token::NtArg(ref e) => arg_to_string(e),
token::NtVis(ref e) => vis_to_string(e), token::NtVis(ref e) => vis_to_string(e),
token::NtLifetime(ref e) => lifetime_to_string(e),
token::NtForeignItem(ref e) => foreign_item_to_string(e), token::NtForeignItem(ref e) => foreign_item_to_string(e),
} }
} }