mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-24 21:53:56 +00:00
Replace extern mod
with extern crate
This patch adds a new keyword `crate` which is intended to replace mod in the context of `extern mod` as part of the issue #9880. The patch doesn't replace all `extern mod` cases since it is necessary to first push a new snapshot 0. The implementation could've been less invasive than this. However I preferred to take this chance to split the `parse_item_foreign_mod` method and pull the `extern crate` part out of there, hence the new method `parse_item_foreign_crate`.
This commit is contained in:
parent
968633b60a
commit
9a6d92c1d7
@ -866,7 +866,10 @@ impl Parser {
|
||||
|
||||
*/
|
||||
|
||||
let opt_abis = self.parse_opt_abis();
|
||||
let opt_abis = if self.eat_keyword(keywords::Extern) {
|
||||
self.parse_opt_abis()
|
||||
} else { None };
|
||||
|
||||
let abis = opt_abis.unwrap_or(AbiSet::Rust());
|
||||
let purity = self.parse_unsafety();
|
||||
self.expect_keyword(keywords::Fn);
|
||||
@ -4308,55 +4311,64 @@ impl Parser {
|
||||
}
|
||||
}
|
||||
|
||||
// parse extern foo; or extern mod foo { ... } or extern { ... }
|
||||
/// Parse extern crate links
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// extern crate extra;
|
||||
/// extern crate foo = "bar";
|
||||
fn parse_item_extern_crate(&mut self,
|
||||
lo: BytePos,
|
||||
visibility: Visibility,
|
||||
attrs: ~[Attribute])
|
||||
-> ItemOrViewItem {
|
||||
|
||||
let (maybe_path, ident) = match self.token {
|
||||
token::IDENT(..) => {
|
||||
let the_ident = self.parse_ident();
|
||||
self.expect_one_of(&[], &[token::EQ, token::SEMI]);
|
||||
let path = if self.token == token::EQ {
|
||||
self.bump();
|
||||
Some(self.parse_str())
|
||||
} else {None};
|
||||
|
||||
self.expect(&token::SEMI);
|
||||
(path, the_ident)
|
||||
}
|
||||
_ => {
|
||||
let token_str = self.this_token_to_str();
|
||||
self.span_fatal(self.span,
|
||||
format!("expected extern crate name but found `{}`",
|
||||
token_str));
|
||||
}
|
||||
};
|
||||
|
||||
IoviViewItem(ast::ViewItem {
|
||||
node: ViewItemExternMod(ident, maybe_path, ast::DUMMY_NODE_ID),
|
||||
attrs: attrs,
|
||||
vis: visibility,
|
||||
span: mk_sp(lo, self.last_span.hi)
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse `extern` for foreign ABIs
|
||||
/// modules.
|
||||
///
|
||||
/// `extern` is expected to have been
|
||||
/// consumed before calling this method
|
||||
///
|
||||
/// # Examples:
|
||||
///
|
||||
/// extern "C" {}
|
||||
/// extern {}
|
||||
fn parse_item_foreign_mod(&mut self,
|
||||
lo: BytePos,
|
||||
opt_abis: Option<AbiSet>,
|
||||
visibility: Visibility,
|
||||
attrs: ~[Attribute],
|
||||
items_allowed: bool)
|
||||
attrs: ~[Attribute])
|
||||
-> ItemOrViewItem {
|
||||
let mut must_be_named_mod = false;
|
||||
if self.is_keyword(keywords::Mod) {
|
||||
must_be_named_mod = true;
|
||||
self.expect_keyword(keywords::Mod);
|
||||
} else if self.token != token::LBRACE {
|
||||
let token_str = self.this_token_to_str();
|
||||
self.span_fatal(self.span,
|
||||
format!("expected `\\{` or `mod` but found `{}`",
|
||||
token_str))
|
||||
}
|
||||
|
||||
let (named, maybe_path, ident) = match self.token {
|
||||
token::IDENT(..) => {
|
||||
let the_ident = self.parse_ident();
|
||||
let path = if self.token == token::EQ {
|
||||
self.bump();
|
||||
Some(self.parse_str())
|
||||
}
|
||||
else { None };
|
||||
(true, path, the_ident)
|
||||
}
|
||||
_ => {
|
||||
if must_be_named_mod {
|
||||
let token_str = self.this_token_to_str();
|
||||
self.span_fatal(self.span,
|
||||
format!("expected foreign module name but \
|
||||
found `{}`",
|
||||
token_str))
|
||||
}
|
||||
|
||||
(false, None,
|
||||
special_idents::clownshoes_foreign_mod)
|
||||
}
|
||||
};
|
||||
|
||||
// extern mod foo { ... } or extern { ... }
|
||||
if items_allowed && self.eat(&token::LBRACE) {
|
||||
// `extern mod foo { ... }` is obsolete.
|
||||
if named {
|
||||
self.obsolete(self.last_span, ObsoleteNamedExternModule);
|
||||
}
|
||||
self.expect(&token::LBRACE);
|
||||
|
||||
let abis = opt_abis.unwrap_or(AbiSet::C());
|
||||
|
||||
@ -4366,35 +4378,13 @@ impl Parser {
|
||||
|
||||
let item = self.mk_item(lo,
|
||||
self.last_span.hi,
|
||||
ident,
|
||||
special_idents::clownshoes_foreign_mod,
|
||||
ItemForeignMod(m),
|
||||
visibility,
|
||||
maybe_append(attrs, Some(inner)));
|
||||
return IoviItem(item);
|
||||
}
|
||||
|
||||
if opt_abis.is_some() {
|
||||
self.span_err(self.span, "an ABI may not be specified here");
|
||||
}
|
||||
|
||||
|
||||
if self.token == token::LPAREN {
|
||||
// `extern mod foo (name = "bar"[,vers = "version"]) is obsolete,
|
||||
// `extern mod foo = "bar#[version]";` should be used.
|
||||
// Parse obsolete options to avoid wired parser errors
|
||||
self.parse_optional_meta();
|
||||
self.obsolete(self.span, ObsoleteExternModAttributesInParens);
|
||||
}
|
||||
// extern mod foo;
|
||||
self.expect(&token::SEMI);
|
||||
IoviViewItem(ast::ViewItem {
|
||||
node: ViewItemExternMod(ident, maybe_path, ast::DUMMY_NODE_ID),
|
||||
attrs: attrs,
|
||||
vis: visibility,
|
||||
span: mk_sp(lo, self.last_span.hi)
|
||||
})
|
||||
}
|
||||
|
||||
// parse type Foo = Bar;
|
||||
fn parse_item_type(&mut self) -> ItemInfo {
|
||||
let ident = self.parse_ident();
|
||||
@ -4504,10 +4494,6 @@ impl Parser {
|
||||
// Parses a string as an ABI spec on an extern type or module. Consumes
|
||||
// the `extern` keyword, if one is found.
|
||||
fn parse_opt_abis(&mut self) -> Option<AbiSet> {
|
||||
if !self.eat_keyword(keywords::Extern) {
|
||||
return None
|
||||
}
|
||||
|
||||
match self.token {
|
||||
token::LIT_STR(s)
|
||||
| token::LIT_STR_RAW(s, _) => {
|
||||
@ -4585,7 +4571,20 @@ impl Parser {
|
||||
});
|
||||
}
|
||||
// either a view item or an item:
|
||||
if self.is_keyword(keywords::Extern) {
|
||||
if self.eat_keyword(keywords::Extern) {
|
||||
let next_is_mod = self.eat_keyword(keywords::Mod);
|
||||
|
||||
if next_is_mod || self.eat_keyword(keywords::Crate) {
|
||||
// NOTE(flaper87): Uncomment this when this changes gets into stage0
|
||||
//
|
||||
// if next_is_mod {
|
||||
// self.span_err(self.span,
|
||||
// format!("`extern mod` is obsolete, use `extern crate` instead \
|
||||
// to refer to external crates."))
|
||||
// }
|
||||
return self.parse_item_extern_crate(lo, visibility, attrs);
|
||||
}
|
||||
|
||||
let opt_abis = self.parse_opt_abis();
|
||||
|
||||
if self.eat_keyword(keywords::Fn) {
|
||||
@ -4600,12 +4599,15 @@ impl Parser {
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
} else {
|
||||
// EXTERN MODULE ITEM (IoviViewItem)
|
||||
return self.parse_item_foreign_mod(lo, opt_abis, visibility, attrs,
|
||||
true);
|
||||
} else if self.token == token::LBRACE {
|
||||
return self.parse_item_foreign_mod(lo, opt_abis, visibility, attrs);
|
||||
}
|
||||
|
||||
let token_str = self.this_token_to_str();
|
||||
self.span_fatal(self.span,
|
||||
format!("expected `\\{` or `fn` but found `{}`", token_str));
|
||||
}
|
||||
|
||||
// the rest are all guaranteed to be items:
|
||||
if self.is_keyword(keywords::Static) {
|
||||
// STATIC ITEM
|
||||
|
@ -462,37 +462,38 @@ declare_special_idents_and_keywords! {
|
||||
(28, Loop, "loop");
|
||||
(29, Match, "match");
|
||||
(30, Mod, "mod");
|
||||
(31, Mut, "mut");
|
||||
(32, Once, "once");
|
||||
(33, Priv, "priv");
|
||||
(34, Pub, "pub");
|
||||
(35, Ref, "ref");
|
||||
(36, Return, "return");
|
||||
(31, Crate, "crate");
|
||||
(32, Mut, "mut");
|
||||
(33, Once, "once");
|
||||
(34, Priv, "priv");
|
||||
(35, Pub, "pub");
|
||||
(36, Ref, "ref");
|
||||
(37, Return, "return");
|
||||
// Static and Self are also special idents (prefill de-dupes)
|
||||
(super::STATIC_KEYWORD_NAME, Static, "static");
|
||||
(super::SELF_KEYWORD_NAME, Self, "self");
|
||||
(37, Struct, "struct");
|
||||
(38, Super, "super");
|
||||
(39, True, "true");
|
||||
(40, Trait, "trait");
|
||||
(41, Type, "type");
|
||||
(42, Unsafe, "unsafe");
|
||||
(43, Use, "use");
|
||||
(44, While, "while");
|
||||
(45, Continue, "continue");
|
||||
(46, Proc, "proc");
|
||||
(47, Box, "box");
|
||||
(38, Struct, "struct");
|
||||
(39, Super, "super");
|
||||
(40, True, "true");
|
||||
(41, Trait, "trait");
|
||||
(42, Type, "type");
|
||||
(43, Unsafe, "unsafe");
|
||||
(44, Use, "use");
|
||||
(45, While, "while");
|
||||
(46, Continue, "continue");
|
||||
(47, Proc, "proc");
|
||||
(48, Box, "box");
|
||||
|
||||
'reserved:
|
||||
(48, Alignof, "alignof");
|
||||
(49, Be, "be");
|
||||
(50, Offsetof, "offsetof");
|
||||
(51, Pure, "pure");
|
||||
(52, Sizeof, "sizeof");
|
||||
(53, Typeof, "typeof");
|
||||
(54, Unsized, "unsized");
|
||||
(55, Yield, "yield");
|
||||
(56, Do, "do");
|
||||
(49, Alignof, "alignof");
|
||||
(50, Be, "be");
|
||||
(51, Offsetof, "offsetof");
|
||||
(52, Pure, "pure");
|
||||
(53, Sizeof, "sizeof");
|
||||
(54, Typeof, "typeof");
|
||||
(55, Unsized, "unsized");
|
||||
(56, Yield, "yield");
|
||||
(57, Do, "do");
|
||||
}
|
||||
}
|
||||
|
||||
|
14
src/test/compile-fail/extern-expected-fn-or-brace.rs
Normal file
14
src/test/compile-fail/extern-expected-fn-or-brace.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
// Verifies that the expected token errors for `extern crate` are
|
||||
// raised
|
||||
|
||||
extern "C" mod foo; //~ERROR expected `{` or `fn` but found `mod`
|
14
src/test/compile-fail/extern-foreign-crate.rs
Normal file
14
src/test/compile-fail/extern-foreign-crate.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
// Verifies that the expected token errors for `extern crate` are
|
||||
// raised
|
||||
|
||||
extern crate foo {} //~ERROR expected one of `=`, `;` but found `{`
|
14
src/test/run-pass/extern-foreign-crate.rs
Normal file
14
src/test/run-pass/extern-foreign-crate.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2013 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.
|
||||
|
||||
extern crate extra;
|
||||
extern mod mystd = "std";
|
||||
|
||||
pub fn main() {}
|
Loading…
Reference in New Issue
Block a user