Auto merge of #42902 - petrochenkov:keydcrate, r=jseyfried
Make `$crate` a keyword Fixes https://github.com/rust-lang/rust/issues/42898 r? @jseyfried or @nrc
This commit is contained in:
commit
5eef7c7966
|
@ -1527,7 +1527,8 @@ impl<'a> State<'a> {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
word(&mut self.s, "::")?
|
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_name(segment.name)?;
|
||||||
self.print_path_parameters(&segment.parameters, colons_before_params)?;
|
self.print_path_parameters(&segment.parameters, colons_before_params)?;
|
||||||
}
|
}
|
||||||
|
@ -1554,7 +1555,8 @@ impl<'a> State<'a> {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
word(&mut self.s, "::")?
|
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_name(segment.name)?;
|
||||||
self.print_path_parameters(&segment.parameters, colons_before_params)?;
|
self.print_path_parameters(&segment.parameters, colons_before_params)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,14 +149,15 @@ impl<'a> Resolver<'a> {
|
||||||
resolve_error(self,
|
resolve_error(self,
|
||||||
view_path.span,
|
view_path.span,
|
||||||
ResolutionError::SelfImportsOnlyAllowedWithin);
|
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_root = self.resolve_crate_root(source.ctxt);
|
||||||
let crate_name = match crate_root.kind {
|
let crate_name = match crate_root.kind {
|
||||||
ModuleKind::Def(_, name) => name,
|
ModuleKind::Def(_, name) => name,
|
||||||
ModuleKind::Block(..) => unreachable!(),
|
ModuleKind::Block(..) => unreachable!(),
|
||||||
};
|
};
|
||||||
source.name = crate_name;
|
source.name = crate_name;
|
||||||
if binding.name == "$crate" {
|
if binding.name == keywords::DollarCrate.name() {
|
||||||
binding.name = crate_name;
|
binding.name = crate_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2665,7 +2665,8 @@ impl<'a> Resolver<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if path.len() > 1 && !global_by_default && result.base_def() != Def::Err &&
|
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 = {
|
let unqualified_result = {
|
||||||
match self.resolve_path(&[*path.last().unwrap()], Some(ns), false, span) {
|
match self.resolve_path(&[*path.last().unwrap()], Some(ns), false, span) {
|
||||||
PathResult::NonModule(path_res) => path_res.base_def(),
|
PathResult::NonModule(path_res) => path_res.base_def(),
|
||||||
|
@ -2718,7 +2719,7 @@ impl<'a> Resolver<'a> {
|
||||||
if i == 0 && ns == TypeNS && ident.name == keywords::CrateRoot.name() {
|
if i == 0 && ns == TypeNS && ident.name == keywords::CrateRoot.name() {
|
||||||
module = Some(self.resolve_crate_root(ident.ctxt.modern()));
|
module = Some(self.resolve_crate_root(ident.ctxt.modern()));
|
||||||
continue
|
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));
|
module = Some(self.resolve_crate_root(ident.ctxt));
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,7 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||||
impl<'a, 'b> Folder for EliminateCrateVar<'a, 'b> {
|
impl<'a, 'b> Folder for EliminateCrateVar<'a, 'b> {
|
||||||
fn fold_path(&mut self, mut path: ast::Path) -> ast::Path {
|
fn fold_path(&mut self, mut path: ast::Path) -> ast::Path {
|
||||||
let ident = path.segments[0].identifier;
|
let ident = path.segments[0].identifier;
|
||||||
if ident.name == "$crate" {
|
if ident.name == keywords::DollarCrate.name() {
|
||||||
path.segments[0].identifier.name = keywords::CrateRoot.name();
|
path.segments[0].identifier.name = keywords::CrateRoot.name();
|
||||||
let module = self.0.resolve_crate_root(ident.ctxt);
|
let module = self.0.resolve_crate_root(ident.ctxt);
|
||||||
if !module.is_local() {
|
if !module.is_local() {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -97,9 +97,8 @@ impl Path {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn default_to_global(mut self) -> Path {
|
pub fn default_to_global(mut self) -> Path {
|
||||||
let name = self.segments[0].identifier.name;
|
if !self.is_global() &&
|
||||||
if !self.is_global() && name != "$crate" &&
|
!::parse::token::Ident(self.segments[0].identifier).is_path_segment_keyword() {
|
||||||
name != keywords::SelfValue.name() && name != keywords::Super.name() {
|
|
||||||
self.segments.insert(0, PathSegment::crate_root());
|
self.segments.insert(0, PathSegment::crate_root());
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
|
|
|
@ -12,7 +12,7 @@ use ast;
|
||||||
use ext::tt::macro_parser;
|
use ext::tt::macro_parser;
|
||||||
use parse::{ParseSess, token};
|
use parse::{ParseSess, token};
|
||||||
use print::pprust;
|
use print::pprust;
|
||||||
use symbol::{keywords, Symbol};
|
use symbol::keywords;
|
||||||
use syntax_pos::{DUMMY_SP, Span, BytePos};
|
use syntax_pos::{DUMMY_SP, Span, BytePos};
|
||||||
use tokenstream;
|
use tokenstream;
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ fn parse_tree<I>(tree: tokenstream::TokenTree,
|
||||||
Some(tokenstream::TokenTree::Token(ident_span, token::Ident(ident))) => {
|
Some(tokenstream::TokenTree::Token(ident_span, token::Ident(ident))) => {
|
||||||
let span = Span { lo: span.lo, ..ident_span };
|
let span = Span { lo: span.lo, ..ident_span };
|
||||||
if ident.name == keywords::Crate.name() {
|
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))
|
TokenTree::Token(span, token::Ident(ident))
|
||||||
} else {
|
} else {
|
||||||
TokenTree::Token(span, token::SubstNt(ident))
|
TokenTree::Token(span, token::SubstNt(ident))
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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`.
|
||||||
|
@ -327,18 +327,23 @@ impl Token {
|
||||||
match self.ident() {
|
match self.ident() {
|
||||||
Some(id) => id.name == keywords::Super.name() ||
|
Some(id) => id.name == keywords::Super.name() ||
|
||||||
id.name == keywords::SelfValue.name() ||
|
id.name == keywords::SelfValue.name() ||
|
||||||
id.name == keywords::SelfType.name(),
|
id.name == keywords::SelfType.name() ||
|
||||||
|
id.name == keywords::DollarCrate.name(),
|
||||||
None => false,
|
None => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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,
|
||||||
|
@ -346,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)]
|
||||||
|
|
|
@ -761,7 +761,7 @@ pub trait PrintState<'a> {
|
||||||
word(self.writer(), "::")?
|
word(self.writer(), "::")?
|
||||||
}
|
}
|
||||||
if segment.identifier.name != keywords::CrateRoot.name() &&
|
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())?;
|
word(self.writer(), &segment.identifier.name.as_str())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2375,7 +2375,7 @@ impl<'a> State<'a> {
|
||||||
-> io::Result<()>
|
-> io::Result<()>
|
||||||
{
|
{
|
||||||
if segment.identifier.name != keywords::CrateRoot.name() &&
|
if segment.identifier.name != keywords::CrateRoot.name() &&
|
||||||
segment.identifier.name != "$crate" {
|
segment.identifier.name != keywords::DollarCrate.name() {
|
||||||
self.print_ident(segment.identifier)?;
|
self.print_ident(segment.identifier)?;
|
||||||
if let Some(ref parameters) = segment.parameters {
|
if let Some(ref parameters) = segment.parameters {
|
||||||
self.print_path_parameters(parameters, colons_before_params)?;
|
self.print_path_parameters(parameters, colons_before_params)?;
|
||||||
|
|
|
@ -237,76 +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, Else, "else")
|
(9, Else, "else")
|
||||||
(8, Enum, "enum")
|
(10, Enum, "enum")
|
||||||
(9, Extern, "extern")
|
(11, Extern, "extern")
|
||||||
(10, False, "false")
|
(12, False, "false")
|
||||||
(11, Fn, "fn")
|
(13, Fn, "fn")
|
||||||
(12, For, "for")
|
(14, For, "for")
|
||||||
(13, If, "if")
|
(15, If, "if")
|
||||||
(14, Impl, "impl")
|
(16, Impl, "impl")
|
||||||
(15, In, "in")
|
(17, In, "in")
|
||||||
(16, Let, "let")
|
(18, Let, "let")
|
||||||
(17, Loop, "loop")
|
(19, Loop, "loop")
|
||||||
(18, Match, "match")
|
(20, Match, "match")
|
||||||
(19, Mod, "mod")
|
(21, Mod, "mod")
|
||||||
(20, Move, "move")
|
(22, Move, "move")
|
||||||
(21, Mut, "mut")
|
(23, Mut, "mut")
|
||||||
(22, Pub, "pub")
|
(24, Pub, "pub")
|
||||||
(23, Ref, "ref")
|
(25, Ref, "ref")
|
||||||
(24, Return, "return")
|
(26, Return, "return")
|
||||||
(25, SelfValue, "self")
|
(27, SelfValue, "self")
|
||||||
(26, SelfType, "Self")
|
(28, SelfType, "Self")
|
||||||
(27, Static, "static")
|
(29, Static, "static")
|
||||||
(28, Struct, "struct")
|
(30, Struct, "struct")
|
||||||
(29, Super, "super")
|
(31, Super, "super")
|
||||||
(30, Trait, "trait")
|
(32, Trait, "trait")
|
||||||
(31, True, "true")
|
(33, True, "true")
|
||||||
(32, Type, "type")
|
(34, Type, "type")
|
||||||
(33, Unsafe, "unsafe")
|
(35, Unsafe, "unsafe")
|
||||||
(34, Use, "use")
|
(36, Use, "use")
|
||||||
(35, Where, "where")
|
(37, Where, "where")
|
||||||
(36, While, "while")
|
(38, While, "while")
|
||||||
|
|
||||||
// Keywords reserved for future use.
|
// Keywords reserved for future use.
|
||||||
(37, Abstract, "abstract")
|
(39, Abstract, "abstract")
|
||||||
(38, Alignof, "alignof")
|
(40, Alignof, "alignof")
|
||||||
(39, Become, "become")
|
(41, Become, "become")
|
||||||
(40, Do, "do")
|
(42, Do, "do")
|
||||||
(41, Final, "final")
|
(43, Final, "final")
|
||||||
(42, Macro, "macro")
|
(44, Macro, "macro")
|
||||||
(43, Offsetof, "offsetof")
|
(45, Offsetof, "offsetof")
|
||||||
(44, Override, "override")
|
(46, Override, "override")
|
||||||
(45, Priv, "priv")
|
(47, Priv, "priv")
|
||||||
(46, Proc, "proc")
|
(48, Proc, "proc")
|
||||||
(47, Pure, "pure")
|
(49, Pure, "pure")
|
||||||
(48, Sizeof, "sizeof")
|
(50, Sizeof, "sizeof")
|
||||||
(49, Typeof, "typeof")
|
(51, Typeof, "typeof")
|
||||||
(50, Unsized, "unsized")
|
(52, Unsized, "unsized")
|
||||||
(51, Virtual, "virtual")
|
(53, Virtual, "virtual")
|
||||||
(52, Yield, "yield")
|
(54, Yield, "yield")
|
||||||
|
|
||||||
// Weak keywords, have special meaning only in specific contexts.
|
// Weak keywords, have special meaning only in specific contexts.
|
||||||
(53, Default, "default")
|
(55, Default, "default")
|
||||||
(54, StaticLifetime, "'static")
|
(56, StaticLifetime, "'static")
|
||||||
(55, Union, "union")
|
(57, Union, "union")
|
||||||
(56, Catch, "catch")
|
(58, Catch, "catch")
|
||||||
|
|
||||||
// A virtual keyword that resolves to the crate root when used in a lexical scope.
|
|
||||||
(57, 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.
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
mod a {}
|
||||||
|
|
||||||
|
macro_rules! m {
|
||||||
|
() => {
|
||||||
|
use a::$crate; //~ ERROR unresolved import `a::$crate`
|
||||||
|
use a::$crate::b; //~ ERROR unresolved import `a::$crate::b`
|
||||||
|
type A = a::$crate; //~ ERROR cannot find type `$crate` in module `a`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m!();
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
macro_rules! m {
|
||||||
|
() => {
|
||||||
|
struct $crate {} //~ ERROR expected identifier, found reserved identifier `$crate`
|
||||||
|
|
||||||
|
use $crate; // OK
|
||||||
|
//~^ WARN `$crate` may not be imported
|
||||||
|
use $crate as $crate; //~ ERROR expected identifier, found reserved identifier `$crate`
|
||||||
|
//~^ WARN `$crate` may not be imported
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m!();
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
struct S;
|
||||||
|
|
||||||
|
impl S {
|
||||||
|
fn f() {}
|
||||||
|
fn g() {
|
||||||
|
use Self::f; //~ ERROR unresolved import
|
||||||
|
pub(in Self::f) struct Z; //~ ERROR Use of undeclared type or module `Self`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -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() {
|
||||||
|
|
Loading…
Reference in New Issue