Skip to content

Make $crate a keyword #42902

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/librustc/hir/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1527,7 +1527,8 @@ impl<'a> State<'a> {
if i > 0 {
word(&mut self.s, "::")?
}
if segment.name != keywords::CrateRoot.name() && segment.name != "$crate" {
if segment.name != keywords::CrateRoot.name() &&
segment.name != keywords::DollarCrate.name() {
self.print_name(segment.name)?;
self.print_path_parameters(&segment.parameters, colons_before_params)?;
}
Expand All @@ -1554,7 +1555,8 @@ impl<'a> State<'a> {
if i > 0 {
word(&mut self.s, "::")?
}
if segment.name != keywords::CrateRoot.name() && segment.name != "$crate" {
if segment.name != keywords::CrateRoot.name() &&
segment.name != keywords::DollarCrate.name() {
self.print_name(segment.name)?;
self.print_path_parameters(&segment.parameters, colons_before_params)?;
}
Expand Down
5 changes: 3 additions & 2 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,15 @@ impl<'a> Resolver<'a> {
resolve_error(self,
view_path.span,
ResolutionError::SelfImportsOnlyAllowedWithin);
} else if source_name == "$crate" && full_path.segments.len() == 1 {
} else if source_name == keywords::DollarCrate.name() &&
full_path.segments.len() == 1 {
let crate_root = self.resolve_crate_root(source.ctxt);
let crate_name = match crate_root.kind {
ModuleKind::Def(_, name) => name,
ModuleKind::Block(..) => unreachable!(),
};
source.name = crate_name;
if binding.name == "$crate" {
if binding.name == keywords::DollarCrate.name() {
binding.name = crate_name;
}

Expand Down
5 changes: 3 additions & 2 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2665,7 +2665,8 @@ impl<'a> Resolver<'a> {
};

if path.len() > 1 && !global_by_default && result.base_def() != Def::Err &&
path[0].name != keywords::CrateRoot.name() && path[0].name != "$crate" {
path[0].name != keywords::CrateRoot.name() &&
path[0].name != keywords::DollarCrate.name() {
let unqualified_result = {
match self.resolve_path(&[*path.last().unwrap()], Some(ns), false, span) {
PathResult::NonModule(path_res) => path_res.base_def(),
Expand Down Expand Up @@ -2718,7 +2719,7 @@ impl<'a> Resolver<'a> {
if i == 0 && ns == TypeNS && ident.name == keywords::CrateRoot.name() {
module = Some(self.resolve_crate_root(ident.ctxt.modern()));
continue
} else if i == 0 && ns == TypeNS && ident.name == "$crate" {
} else if i == 0 && ns == TypeNS && ident.name == keywords::DollarCrate.name() {
module = Some(self.resolve_crate_root(ident.ctxt));
continue
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_resolve/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ impl<'a> base::Resolver for Resolver<'a> {
impl<'a, 'b> Folder for EliminateCrateVar<'a, 'b> {
fn fold_path(&mut self, mut path: ast::Path) -> ast::Path {
let ident = path.segments[0].identifier;
if ident.name == "$crate" {
if ident.name == keywords::DollarCrate.name() {
path.segments[0].identifier.name = keywords::CrateRoot.name();
let module = self.0.resolve_crate_root(ident.ctxt);
if !module.is_local() {
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/html/highlight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ impl<'a> Classifier<'a> {
"Some" | "None" | "Ok" | "Err" => Class::PreludeVal,

"$crate" => Class::KeyWord,
_ if tas.tok.is_any_keyword() => Class::KeyWord,
_ if tas.tok.is_reserved_ident() => Class::KeyWord,

_ => {
if self.in_macro_nonterminal {
Expand Down
5 changes: 2 additions & 3 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,8 @@ impl Path {
}

pub fn default_to_global(mut self) -> Path {
let name = self.segments[0].identifier.name;
if !self.is_global() && name != "$crate" &&
name != keywords::SelfValue.name() && name != keywords::Super.name() {
if !self.is_global() &&
!::parse::token::Ident(self.segments[0].identifier).is_path_segment_keyword() {
self.segments.insert(0, PathSegment::crate_root());
}
self
Expand Down
4 changes: 2 additions & 2 deletions src/libsyntax/ext/tt/quoted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use ast;
use ext::tt::macro_parser;
use parse::{ParseSess, token};
use print::pprust;
use symbol::{keywords, Symbol};
use symbol::keywords;
use syntax_pos::{DUMMY_SP, Span, BytePos};
use tokenstream;

Expand Down Expand Up @@ -196,7 +196,7 @@ fn parse_tree<I>(tree: tokenstream::TokenTree,
Some(tokenstream::TokenTree::Token(ident_span, token::Ident(ident))) => {
let span = Span { lo: span.lo, ..ident_span };
if ident.name == keywords::Crate.name() {
let ident = ast::Ident { name: Symbol::intern("$crate"), ..ident };
let ident = ast::Ident { name: keywords::DollarCrate.name(), ..ident };
TokenTree::Token(span, token::Ident(ident))
} else {
TokenTree::Token(span, token::SubstNt(ident))
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/parse/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1283,7 +1283,7 @@ impl<'a> StringReader<'a> {
});
let keyword_checking_token = &token::Ident(keyword_checking_ident);
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) {
self.err_span_(start, last_bpos, "lifetimes cannot use keyword names");
}
Expand Down
46 changes: 14 additions & 32 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,14 +511,13 @@ impl<'a> Parser<'a> {
}

pub fn this_token_descr(&self) -> String {
let s = self.this_token_to_string();
if self.token.is_strict_keyword() {
format!("keyword `{}`", s)
} else if self.token.is_reserved_keyword() {
format!("reserved keyword `{}`", s)
} else {
format!("`{}`", s)
}
let prefix = match &self.token {
t if t.is_special_ident() => "reserved identifier ",
t if t.is_used_keyword() => "keyword ",
t if t.is_unused_keyword() => "reserved keyword ",
_ => "",
};
format!("{}`{}`", prefix, self.this_token_to_string())
}

pub fn unexpected_last<T>(&self, t: &token::Token) -> PResult<'a, T> {
Expand Down Expand Up @@ -637,10 +636,12 @@ impl<'a> Parser<'a> {
}

pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> {
self.check_strict_keywords();
self.check_reserved_keywords();
match self.token {
token::Ident(i) => {
if self.token.is_reserved_ident() {
self.span_err(self.span, &format!("expected identifier, found {}",
self.this_token_descr()));
}
self.bump();
Ok(i)
}
Expand Down Expand Up @@ -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 {
if self.token.is_ident() {
true
Expand Down Expand Up @@ -2301,7 +2283,7 @@ impl<'a> Parser<'a> {
ex = ExprKind::Break(lt, e);
hi = self.prev_span;
} 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
let mut db = self.fatal("expected expression, found statement (`let`)");
db.note("variable declaration using `let` is a statement");
Expand Down Expand Up @@ -3540,7 +3522,7 @@ impl<'a> Parser<'a> {
// Parse box pat
let subpat = self.parse_pat()?;
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() {
// Parse ident @ pat
// This can give false positives and parse nullary enums,
Expand Down Expand Up @@ -3815,7 +3797,7 @@ impl<'a> Parser<'a> {

fn is_union_item(&self) -> bool {
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 {
Expand Down
30 changes: 20 additions & 10 deletions src/libsyntax/parse/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl Lit {
fn ident_can_begin_expr(ident: ast::Ident) -> bool {
let ident_token: Token = Ident(ident);

!ident_token.is_any_keyword() ||
!ident_token.is_reserved_ident() ||
ident_token.is_path_segment_keyword() ||
[
keywords::Do.name(),
Expand All @@ -110,7 +110,7 @@ fn ident_can_begin_expr(ident: ast::Ident) -> bool {
fn ident_can_begin_type(ident: ast::Ident) -> bool {
let ident_token: Token = Ident(ident);

!ident_token.is_any_keyword() ||
!ident_token.is_reserved_ident() ||
ident_token.is_path_segment_keyword() ||
[
keywords::For.name(),
Expand Down Expand Up @@ -315,7 +315,7 @@ impl Token {

pub fn is_path_start(&self) -> bool {
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`.
Expand All @@ -327,31 +327,41 @@ impl Token {
match self.ident() {
Some(id) => id.name == keywords::Super.name() ||
id.name == keywords::SelfValue.name() ||
id.name == keywords::SelfType.name(),
id.name == keywords::SelfType.name() ||
id.name == keywords::DollarCrate.name(),
None => false,
}
}

/// Returns `true` if the token is either a strict or reserved keyword.
pub fn is_any_keyword(&self) -> bool {
self.is_strict_keyword() || self.is_reserved_keyword()
// Returns true for reserved identifiers used internally for elided lifetimes,
// unnamed method parameters, crate root module, error recovery etc.
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.
pub fn is_strict_keyword(&self) -> bool {
/// Returns `true` if the token is a keyword used in the language.
pub fn is_used_keyword(&self) -> bool {
match self.ident() {
Some(id) => id.name >= keywords::As.name() && id.name <= keywords::While.name(),
_ => false,
}
}

/// 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() {
Some(id) => id.name >= keywords::Abstract.name() && id.name <= keywords::Yield.name(),
_ => 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)]
Expand Down
4 changes: 2 additions & 2 deletions src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,7 @@ pub trait PrintState<'a> {
word(self.writer(), "::")?
}
if segment.identifier.name != keywords::CrateRoot.name() &&
segment.identifier.name != "$crate" {
segment.identifier.name != keywords::DollarCrate.name() {
word(self.writer(), &segment.identifier.name.as_str())?;
}
}
Expand Down Expand Up @@ -2375,7 +2375,7 @@ impl<'a> State<'a> {
-> io::Result<()>
{
if segment.identifier.name != keywords::CrateRoot.name() &&
segment.identifier.name != "$crate" {
segment.identifier.name != keywords::DollarCrate.name() {
self.print_ident(segment.identifier)?;
if let Some(ref parameters) = segment.parameters {
self.print_path_parameters(parameters, colons_before_params)?;
Expand Down
Loading