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 @@ pub fn print_path(&mut self,
|
||||
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)?;
|
||||
}
|
||||
@ -1554,7 +1555,8 @@ pub fn print_qpath(&mut self,
|
||||
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)?;
|
||||
}
|
||||
|
@ -149,14 +149,15 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -2665,7 +2665,8 @@ fn resolve_qpath(&mut self,
|
||||
};
|
||||
|
||||
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(),
|
||||
@ -2718,7 +2719,7 @@ fn resolve_path(&mut self,
|
||||
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
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ fn eliminate_crate_var(&mut self, item: P<ast::Item>) -> P<ast::Item> {
|
||||
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() {
|
||||
|
@ -300,7 +300,7 @@ fn write_token<W: Writer>(&mut self,
|
||||
"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 {
|
||||
|
@ -97,9 +97,8 @@ pub fn from_ident(s: Span, identifier: Ident) -> 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
|
||||
|
@ -12,7 +12,7 @@
|
||||
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;
|
||||
|
||||
@ -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))
|
||||
|
@ -1283,7 +1283,7 @@ fn next_token_inner(&mut self) -> Result<token::Token, ()> {
|
||||
});
|
||||
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");
|
||||
}
|
||||
|
@ -511,14 +511,13 @@ pub fn this_token_to_string(&self) -> String {
|
||||
}
|
||||
|
||||
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> {
|
||||
@ -637,10 +636,12 @@ fn interpolated_or_expr_span(&self,
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
@ -713,25 +714,6 @@ pub fn expect_keyword(&mut self, kw: keywords::Keyword) -> PResult<'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
|
||||
@ -2301,7 +2283,7 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
|
||||
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");
|
||||
@ -3540,7 +3522,7 @@ pub fn parse_pat(&mut self) -> PResult<'a, P<Pat>> {
|
||||
// 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,
|
||||
@ -3815,7 +3797,7 @@ fn is_catch_expr(&mut self) -> bool {
|
||||
|
||||
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 {
|
||||
|
@ -87,7 +87,7 @@ pub fn short_name(&self) -> &'static str {
|
||||
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(),
|
||||
@ -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(),
|
||||
@ -315,7 +315,7 @@ pub fn is_qpath_start(&self) -> bool {
|
||||
|
||||
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`.
|
||||
@ -327,18 +327,23 @@ pub fn is_path_segment_keyword(&self) -> bool {
|
||||
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,
|
||||
@ -346,12 +351,17 @@ pub fn is_strict_keyword(&self) -> bool {
|
||||
}
|
||||
|
||||
/// 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)]
|
||||
|
@ -761,7 +761,7 @@ fn print_attribute_inline(&mut self, attr: &ast::Attribute,
|
||||
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())?;
|
||||
}
|
||||
}
|
||||
@ -2375,7 +2375,7 @@ fn print_path_segment(&mut self,
|
||||
-> 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)?;
|
||||
|
@ -237,76 +237,76 @@ fn fresh() -> Self {
|
||||
// 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
|
||||
// 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.
|
||||
declare_keywords! {
|
||||
// Invalid identifier
|
||||
// Special reserved identifiers used internally for elided lifetimes,
|
||||
// unnamed method parameters, crate root module, error recovery etc.
|
||||
(0, Invalid, "")
|
||||
(1, CrateRoot, "{{root}}")
|
||||
(2, DollarCrate, "$crate")
|
||||
|
||||
// Strict keywords used in the language.
|
||||
(1, As, "as")
|
||||
(2, Box, "box")
|
||||
(3, Break, "break")
|
||||
(4, Const, "const")
|
||||
(5, Continue, "continue")
|
||||
(6, Crate, "crate")
|
||||
(7, Else, "else")
|
||||
(8, Enum, "enum")
|
||||
(9, Extern, "extern")
|
||||
(10, False, "false")
|
||||
(11, Fn, "fn")
|
||||
(12, For, "for")
|
||||
(13, If, "if")
|
||||
(14, Impl, "impl")
|
||||
(15, In, "in")
|
||||
(16, Let, "let")
|
||||
(17, Loop, "loop")
|
||||
(18, Match, "match")
|
||||
(19, Mod, "mod")
|
||||
(20, Move, "move")
|
||||
(21, Mut, "mut")
|
||||
(22, Pub, "pub")
|
||||
(23, Ref, "ref")
|
||||
(24, Return, "return")
|
||||
(25, SelfValue, "self")
|
||||
(26, SelfType, "Self")
|
||||
(27, Static, "static")
|
||||
(28, Struct, "struct")
|
||||
(29, Super, "super")
|
||||
(30, Trait, "trait")
|
||||
(31, True, "true")
|
||||
(32, Type, "type")
|
||||
(33, Unsafe, "unsafe")
|
||||
(34, Use, "use")
|
||||
(35, Where, "where")
|
||||
(36, While, "while")
|
||||
// Keywords used in the language.
|
||||
(3, As, "as")
|
||||
(4, Box, "box")
|
||||
(5, Break, "break")
|
||||
(6, Const, "const")
|
||||
(7, Continue, "continue")
|
||||
(8, Crate, "crate")
|
||||
(9, Else, "else")
|
||||
(10, Enum, "enum")
|
||||
(11, Extern, "extern")
|
||||
(12, False, "false")
|
||||
(13, Fn, "fn")
|
||||
(14, For, "for")
|
||||
(15, If, "if")
|
||||
(16, Impl, "impl")
|
||||
(17, In, "in")
|
||||
(18, Let, "let")
|
||||
(19, Loop, "loop")
|
||||
(20, Match, "match")
|
||||
(21, Mod, "mod")
|
||||
(22, Move, "move")
|
||||
(23, Mut, "mut")
|
||||
(24, Pub, "pub")
|
||||
(25, Ref, "ref")
|
||||
(26, Return, "return")
|
||||
(27, SelfValue, "self")
|
||||
(28, SelfType, "Self")
|
||||
(29, Static, "static")
|
||||
(30, Struct, "struct")
|
||||
(31, Super, "super")
|
||||
(32, Trait, "trait")
|
||||
(33, True, "true")
|
||||
(34, Type, "type")
|
||||
(35, Unsafe, "unsafe")
|
||||
(36, Use, "use")
|
||||
(37, Where, "where")
|
||||
(38, While, "while")
|
||||
|
||||
// Keywords reserved for future use.
|
||||
(37, Abstract, "abstract")
|
||||
(38, Alignof, "alignof")
|
||||
(39, Become, "become")
|
||||
(40, Do, "do")
|
||||
(41, Final, "final")
|
||||
(42, Macro, "macro")
|
||||
(43, Offsetof, "offsetof")
|
||||
(44, Override, "override")
|
||||
(45, Priv, "priv")
|
||||
(46, Proc, "proc")
|
||||
(47, Pure, "pure")
|
||||
(48, Sizeof, "sizeof")
|
||||
(49, Typeof, "typeof")
|
||||
(50, Unsized, "unsized")
|
||||
(51, Virtual, "virtual")
|
||||
(52, Yield, "yield")
|
||||
(39, Abstract, "abstract")
|
||||
(40, Alignof, "alignof")
|
||||
(41, Become, "become")
|
||||
(42, Do, "do")
|
||||
(43, Final, "final")
|
||||
(44, Macro, "macro")
|
||||
(45, Offsetof, "offsetof")
|
||||
(46, Override, "override")
|
||||
(47, Priv, "priv")
|
||||
(48, Proc, "proc")
|
||||
(49, Pure, "pure")
|
||||
(50, Sizeof, "sizeof")
|
||||
(51, Typeof, "typeof")
|
||||
(52, Unsized, "unsized")
|
||||
(53, Virtual, "virtual")
|
||||
(54, Yield, "yield")
|
||||
|
||||
// Weak keywords, have special meaning only in specific contexts.
|
||||
(53, Default, "default")
|
||||
(54, StaticLifetime, "'static")
|
||||
(55, Union, "union")
|
||||
(56, Catch, "catch")
|
||||
|
||||
// A virtual keyword that resolves to the crate root when used in a lexical scope.
|
||||
(57, CrateRoot, "{{root}}")
|
||||
(55, Default, "default")
|
||||
(56, StaticLifetime, "'static")
|
||||
(57, Union, "union")
|
||||
(58, Catch, "catch")
|
||||
}
|
||||
|
||||
// If an interner exists in TLS, return it. Otherwise, prepare a fresh one.
|
||||
|
23
src/test/compile-fail/dollar-crate-is-keyword-2.rs
Normal file
23
src/test/compile-fail/dollar-crate-is-keyword-2.rs
Normal file
@ -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() {}
|
24
src/test/compile-fail/dollar-crate-is-keyword.rs
Normal file
24
src/test/compile-fail/dollar-crate-is-keyword.rs
Normal file
@ -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() {}
|
21
src/test/compile-fail/use-self-type.rs
Normal file
21
src/test/compile-fail/use-self-type.rs
Normal file
@ -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
|
||||
|
||||
fn macro() { //~ ERROR `macro` is a reserved keyword
|
||||
fn macro() { //~ ERROR expected identifier, found reserved keyword `macro`
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
|
Loading…
Reference in New Issue
Block a user