1
Fork 0

Change some terminology around keywords and reserved identifiers

This commit is contained in:
petrochenkov 2017-06-29 13:16:35 +03:00 committed by Vadim Petrochenkov
parent e03948ef3e
commit b33fd6d759
7 changed files with 99 additions and 109 deletions

View file

@ -300,7 +300,7 @@ impl<'a> Classifier<'a> {
"Some" | "None" | "Ok" | "Err" => Class::PreludeVal, "Some" | "None" | "Ok" | "Err" => Class::PreludeVal,
"$crate" => Class::KeyWord, "$crate" => Class::KeyWord,
_ if tas.tok.is_any_keyword() => Class::KeyWord, _ if tas.tok.is_reserved_ident() => Class::KeyWord,
_ => { _ => {
if self.in_macro_nonterminal { if self.in_macro_nonterminal {

View file

@ -1283,7 +1283,7 @@ impl<'a> StringReader<'a> {
}); });
let keyword_checking_token = &token::Ident(keyword_checking_ident); let keyword_checking_token = &token::Ident(keyword_checking_ident);
let last_bpos = self.pos; let last_bpos = self.pos;
if keyword_checking_token.is_any_keyword() && if keyword_checking_token.is_reserved_ident() &&
!keyword_checking_token.is_keyword(keywords::Static) { !keyword_checking_token.is_keyword(keywords::Static) {
self.err_span_(start, last_bpos, "lifetimes cannot use keyword names"); self.err_span_(start, last_bpos, "lifetimes cannot use keyword names");
} }

View file

@ -511,14 +511,13 @@ impl<'a> Parser<'a> {
} }
pub fn this_token_descr(&self) -> String { pub fn this_token_descr(&self) -> String {
let s = self.this_token_to_string(); let prefix = match &self.token {
if self.token.is_strict_keyword() { t if t.is_special_ident() => "reserved identifier ",
format!("keyword `{}`", s) t if t.is_used_keyword() => "keyword ",
} else if self.token.is_reserved_keyword() { t if t.is_unused_keyword() => "reserved keyword ",
format!("reserved keyword `{}`", s) _ => "",
} else { };
format!("`{}`", s) format!("{}`{}`", prefix, self.this_token_to_string())
}
} }
pub fn unexpected_last<T>(&self, t: &token::Token) -> PResult<'a, T> { pub fn unexpected_last<T>(&self, t: &token::Token) -> PResult<'a, T> {
@ -637,10 +636,12 @@ impl<'a> Parser<'a> {
} }
pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> { pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> {
self.check_strict_keywords();
self.check_reserved_keywords();
match self.token { match self.token {
token::Ident(i) => { token::Ident(i) => {
if self.token.is_reserved_ident() {
self.span_err(self.span, &format!("expected identifier, found {}",
self.this_token_descr()));
}
self.bump(); self.bump();
Ok(i) Ok(i)
} }
@ -713,25 +714,6 @@ impl<'a> Parser<'a> {
} }
} }
/// Signal an error if the given string is a strict keyword
pub fn check_strict_keywords(&mut self) {
if self.token.is_strict_keyword() {
let token_str = self.this_token_to_string();
let span = self.span;
self.span_err(span,
&format!("expected identifier, found keyword `{}`",
token_str));
}
}
/// Signal an error if the current token is a reserved keyword
pub fn check_reserved_keywords(&mut self) {
if self.token.is_reserved_keyword() {
let token_str = self.this_token_to_string();
self.fatal(&format!("`{}` is a reserved keyword", token_str)).emit()
}
}
fn check_ident(&mut self) -> bool { fn check_ident(&mut self) -> bool {
if self.token.is_ident() { if self.token.is_ident() {
true true
@ -2301,7 +2283,7 @@ impl<'a> Parser<'a> {
ex = ExprKind::Break(lt, e); ex = ExprKind::Break(lt, e);
hi = self.prev_span; hi = self.prev_span;
} else if self.token.is_keyword(keywords::Let) { } else if self.token.is_keyword(keywords::Let) {
// Catch this syntax error here, instead of in `check_strict_keywords`, so // Catch this syntax error here, instead of in `parse_ident`, so
// that we can explicitly mention that let is not to be used as an expression // that we can explicitly mention that let is not to be used as an expression
let mut db = self.fatal("expected expression, found statement (`let`)"); let mut db = self.fatal("expected expression, found statement (`let`)");
db.note("variable declaration using `let` is a statement"); db.note("variable declaration using `let` is a statement");
@ -3540,7 +3522,7 @@ impl<'a> Parser<'a> {
// Parse box pat // Parse box pat
let subpat = self.parse_pat()?; let subpat = self.parse_pat()?;
pat = PatKind::Box(subpat); pat = PatKind::Box(subpat);
} else if self.token.is_ident() && !self.token.is_any_keyword() && } else if self.token.is_ident() && !self.token.is_reserved_ident() &&
self.parse_as_ident() { self.parse_as_ident() {
// Parse ident @ pat // Parse ident @ pat
// This can give false positives and parse nullary enums, // This can give false positives and parse nullary enums,
@ -3815,7 +3797,7 @@ impl<'a> Parser<'a> {
fn is_union_item(&self) -> bool { fn is_union_item(&self) -> bool {
self.token.is_keyword(keywords::Union) && self.token.is_keyword(keywords::Union) &&
self.look_ahead(1, |t| t.is_ident() && !t.is_any_keyword()) self.look_ahead(1, |t| t.is_ident() && !t.is_reserved_ident())
} }
fn is_defaultness(&self) -> bool { fn is_defaultness(&self) -> bool {

View file

@ -87,7 +87,7 @@ impl Lit {
fn ident_can_begin_expr(ident: ast::Ident) -> bool { fn ident_can_begin_expr(ident: ast::Ident) -> bool {
let ident_token: Token = Ident(ident); let ident_token: Token = Ident(ident);
!ident_token.is_any_keyword() || !ident_token.is_reserved_ident() ||
ident_token.is_path_segment_keyword() || ident_token.is_path_segment_keyword() ||
[ [
keywords::Do.name(), keywords::Do.name(),
@ -110,7 +110,7 @@ fn ident_can_begin_expr(ident: ast::Ident) -> bool {
fn ident_can_begin_type(ident: ast::Ident) -> bool { fn ident_can_begin_type(ident: ast::Ident) -> bool {
let ident_token: Token = Ident(ident); let ident_token: Token = Ident(ident);
!ident_token.is_any_keyword() || !ident_token.is_reserved_ident() ||
ident_token.is_path_segment_keyword() || ident_token.is_path_segment_keyword() ||
[ [
keywords::For.name(), keywords::For.name(),
@ -315,7 +315,7 @@ impl Token {
pub fn is_path_start(&self) -> bool { pub fn is_path_start(&self) -> bool {
self == &ModSep || self.is_qpath_start() || self.is_path() || self == &ModSep || self.is_qpath_start() || self.is_path() ||
self.is_path_segment_keyword() || self.is_ident() && !self.is_any_keyword() self.is_path_segment_keyword() || self.is_ident() && !self.is_reserved_ident()
} }
/// Returns `true` if the token is a given keyword, `kw`. /// Returns `true` if the token is a given keyword, `kw`.
@ -333,13 +333,17 @@ impl Token {
} }
} }
/// Returns `true` if the token is either a strict or reserved keyword. // Returns true for reserved identifiers used internally for elided lifetimes,
pub fn is_any_keyword(&self) -> bool { // unnamed method parameters, crate root module, error recovery etc.
self.is_strict_keyword() || self.is_reserved_keyword() pub fn is_special_ident(&self) -> bool {
match self.ident() {
Some(id) => id.name <= keywords::DollarCrate.name(),
_ => false,
}
} }
/// Returns `true` if the token is a strict keyword. /// Returns `true` if the token is a keyword used in the language.
pub fn is_strict_keyword(&self) -> bool { pub fn is_used_keyword(&self) -> bool {
match self.ident() { match self.ident() {
Some(id) => id.name >= keywords::As.name() && id.name <= keywords::While.name(), Some(id) => id.name >= keywords::As.name() && id.name <= keywords::While.name(),
_ => false, _ => false,
@ -347,12 +351,17 @@ impl Token {
} }
/// Returns `true` if the token is a keyword reserved for possible future use. /// Returns `true` if the token is a keyword reserved for possible future use.
pub fn is_reserved_keyword(&self) -> bool { pub fn is_unused_keyword(&self) -> bool {
match self.ident() { match self.ident() {
Some(id) => id.name >= keywords::Abstract.name() && id.name <= keywords::Yield.name(), Some(id) => id.name >= keywords::Abstract.name() && id.name <= keywords::Yield.name(),
_ => false, _ => false,
} }
} }
/// Returns `true` if the token is either a special identifier or a keyword.
pub fn is_reserved_ident(&self) -> bool {
self.is_special_ident() || self.is_used_keyword() || self.is_unused_keyword()
}
} }
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash)] #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash)]

View file

@ -237,77 +237,76 @@ macro_rules! declare_keywords {(
// NB: leaving holes in the ident table is bad! a different ident will get // NB: leaving holes in the ident table is bad! a different ident will get
// interned with the id from the hole, but it will be between the min and max // interned with the id from the hole, but it will be between the min and max
// of the reserved words, and thus tagged as "reserved". // of the reserved words, and thus tagged as "reserved".
// After modifying this list adjust `is_strict_keyword`/`is_reserved_keyword`, // After modifying this list adjust `is_special_ident`, `is_used_keyword`/`is_unused_keyword`,
// this should be rarely necessary though if the keywords are kept in alphabetic order. // this should be rarely necessary though if the keywords are kept in alphabetic order.
declare_keywords! { declare_keywords! {
// Invalid identifier // Special reserved identifiers used internally for elided lifetimes,
// unnamed method parameters, crate root module, error recovery etc.
(0, Invalid, "") (0, Invalid, "")
(1, CrateRoot, "{{root}}")
(2, DollarCrate, "$crate")
// Strict keywords used in the language. // Keywords used in the language.
(1, As, "as") (3, As, "as")
(2, Box, "box") (4, Box, "box")
(3, Break, "break") (5, Break, "break")
(4, Const, "const") (6, Const, "const")
(5, Continue, "continue") (7, Continue, "continue")
(6, Crate, "crate") (8, Crate, "crate")
(7, DollarCrate, "$crate") (9, Else, "else")
(8, Else, "else") (10, Enum, "enum")
(9, Enum, "enum") (11, Extern, "extern")
(10, Extern, "extern") (12, False, "false")
(11, False, "false") (13, Fn, "fn")
(12, Fn, "fn") (14, For, "for")
(13, For, "for") (15, If, "if")
(14, If, "if") (16, Impl, "impl")
(15, Impl, "impl") (17, In, "in")
(16, In, "in") (18, Let, "let")
(17, Let, "let") (19, Loop, "loop")
(18, Loop, "loop") (20, Match, "match")
(19, Match, "match") (21, Mod, "mod")
(20, Mod, "mod") (22, Move, "move")
(21, Move, "move") (23, Mut, "mut")
(22, Mut, "mut") (24, Pub, "pub")
(23, Pub, "pub") (25, Ref, "ref")
(24, Ref, "ref") (26, Return, "return")
(25, Return, "return") (27, SelfValue, "self")
(26, SelfValue, "self") (28, SelfType, "Self")
(27, SelfType, "Self") (29, Static, "static")
(28, Static, "static") (30, Struct, "struct")
(29, Struct, "struct") (31, Super, "super")
(30, Super, "super") (32, Trait, "trait")
(31, Trait, "trait") (33, True, "true")
(32, True, "true") (34, Type, "type")
(33, Type, "type") (35, Unsafe, "unsafe")
(34, Unsafe, "unsafe") (36, Use, "use")
(35, Use, "use") (37, Where, "where")
(36, Where, "where") (38, While, "while")
(37, While, "while")
// Keywords reserved for future use. // Keywords reserved for future use.
(38, Abstract, "abstract") (39, Abstract, "abstract")
(39, Alignof, "alignof") (40, Alignof, "alignof")
(40, Become, "become") (41, Become, "become")
(41, Do, "do") (42, Do, "do")
(42, Final, "final") (43, Final, "final")
(43, Macro, "macro") (44, Macro, "macro")
(44, Offsetof, "offsetof") (45, Offsetof, "offsetof")
(45, Override, "override") (46, Override, "override")
(46, Priv, "priv") (47, Priv, "priv")
(47, Proc, "proc") (48, Proc, "proc")
(48, Pure, "pure") (49, Pure, "pure")
(49, Sizeof, "sizeof") (50, Sizeof, "sizeof")
(50, Typeof, "typeof") (51, Typeof, "typeof")
(51, Unsized, "unsized") (52, Unsized, "unsized")
(52, Virtual, "virtual") (53, Virtual, "virtual")
(53, Yield, "yield") (54, Yield, "yield")
// Weak keywords, have special meaning only in specific contexts. // Weak keywords, have special meaning only in specific contexts.
(54, Default, "default") (55, Default, "default")
(55, StaticLifetime, "'static") (56, StaticLifetime, "'static")
(56, Union, "union") (57, Union, "union")
(57, Catch, "catch") (58, Catch, "catch")
// A virtual keyword that resolves to the crate root when used in a lexical scope.
(58, CrateRoot, "{{root}}")
} }
// If an interner exists in TLS, return it. Otherwise, prepare a fresh one. // If an interner exists in TLS, return it. Otherwise, prepare a fresh one.

View file

@ -10,11 +10,11 @@
macro_rules! m { macro_rules! m {
() => { () => {
struct $crate {} //~ ERROR expected identifier, found keyword `$crate` struct $crate {} //~ ERROR expected identifier, found reserved identifier `$crate`
use $crate; // OK use $crate; // OK
//~^ WARN `$crate` may not be imported //~^ WARN `$crate` may not be imported
use $crate as $crate; //~ ERROR expected identifier, found keyword `$crate` use $crate as $crate; //~ ERROR expected identifier, found reserved identifier `$crate`
//~^ WARN `$crate` may not be imported //~^ WARN `$crate` may not be imported
} }
} }

View file

@ -10,7 +10,7 @@
// compile-flags: -Z parse-only // compile-flags: -Z parse-only
fn macro() { //~ ERROR `macro` is a reserved keyword fn macro() { //~ ERROR expected identifier, found reserved keyword `macro`
} }
pub fn main() { pub fn main() {