mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-03 18:43:38 +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 abis = opt_abis.unwrap_or(AbiSet::Rust());
|
||||||
let purity = self.parse_unsafety();
|
let purity = self.parse_unsafety();
|
||||||
self.expect_keyword(keywords::Fn);
|
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,
|
fn parse_item_foreign_mod(&mut self,
|
||||||
lo: BytePos,
|
lo: BytePos,
|
||||||
opt_abis: Option<AbiSet>,
|
opt_abis: Option<AbiSet>,
|
||||||
visibility: Visibility,
|
visibility: Visibility,
|
||||||
attrs: ~[Attribute],
|
attrs: ~[Attribute])
|
||||||
items_allowed: bool)
|
|
||||||
-> ItemOrViewItem {
|
-> 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 {
|
self.expect(&token::LBRACE);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
let abis = opt_abis.unwrap_or(AbiSet::C());
|
let abis = opt_abis.unwrap_or(AbiSet::C());
|
||||||
|
|
||||||
@ -4366,35 +4378,13 @@ impl Parser {
|
|||||||
|
|
||||||
let item = self.mk_item(lo,
|
let item = self.mk_item(lo,
|
||||||
self.last_span.hi,
|
self.last_span.hi,
|
||||||
ident,
|
special_idents::clownshoes_foreign_mod,
|
||||||
ItemForeignMod(m),
|
ItemForeignMod(m),
|
||||||
visibility,
|
visibility,
|
||||||
maybe_append(attrs, Some(inner)));
|
maybe_append(attrs, Some(inner)));
|
||||||
return IoviItem(item);
|
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;
|
// parse type Foo = Bar;
|
||||||
fn parse_item_type(&mut self) -> ItemInfo {
|
fn parse_item_type(&mut self) -> ItemInfo {
|
||||||
let ident = self.parse_ident();
|
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
|
// Parses a string as an ABI spec on an extern type or module. Consumes
|
||||||
// the `extern` keyword, if one is found.
|
// the `extern` keyword, if one is found.
|
||||||
fn parse_opt_abis(&mut self) -> Option<AbiSet> {
|
fn parse_opt_abis(&mut self) -> Option<AbiSet> {
|
||||||
if !self.eat_keyword(keywords::Extern) {
|
|
||||||
return None
|
|
||||||
}
|
|
||||||
|
|
||||||
match self.token {
|
match self.token {
|
||||||
token::LIT_STR(s)
|
token::LIT_STR(s)
|
||||||
| token::LIT_STR_RAW(s, _) => {
|
| token::LIT_STR_RAW(s, _) => {
|
||||||
@ -4585,7 +4571,20 @@ impl Parser {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
// either a view item or an item:
|
// 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();
|
let opt_abis = self.parse_opt_abis();
|
||||||
|
|
||||||
if self.eat_keyword(keywords::Fn) {
|
if self.eat_keyword(keywords::Fn) {
|
||||||
@ -4600,12 +4599,15 @@ impl Parser {
|
|||||||
visibility,
|
visibility,
|
||||||
maybe_append(attrs, extra_attrs));
|
maybe_append(attrs, extra_attrs));
|
||||||
return IoviItem(item);
|
return IoviItem(item);
|
||||||
} else {
|
} else if self.token == token::LBRACE {
|
||||||
// EXTERN MODULE ITEM (IoviViewItem)
|
return self.parse_item_foreign_mod(lo, opt_abis, visibility, attrs);
|
||||||
return self.parse_item_foreign_mod(lo, opt_abis, visibility, attrs,
|
|
||||||
true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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:
|
// the rest are all guaranteed to be items:
|
||||||
if self.is_keyword(keywords::Static) {
|
if self.is_keyword(keywords::Static) {
|
||||||
// STATIC ITEM
|
// STATIC ITEM
|
||||||
|
@ -462,37 +462,38 @@ declare_special_idents_and_keywords! {
|
|||||||
(28, Loop, "loop");
|
(28, Loop, "loop");
|
||||||
(29, Match, "match");
|
(29, Match, "match");
|
||||||
(30, Mod, "mod");
|
(30, Mod, "mod");
|
||||||
(31, Mut, "mut");
|
(31, Crate, "crate");
|
||||||
(32, Once, "once");
|
(32, Mut, "mut");
|
||||||
(33, Priv, "priv");
|
(33, Once, "once");
|
||||||
(34, Pub, "pub");
|
(34, Priv, "priv");
|
||||||
(35, Ref, "ref");
|
(35, Pub, "pub");
|
||||||
(36, Return, "return");
|
(36, Ref, "ref");
|
||||||
|
(37, Return, "return");
|
||||||
// Static and Self are also special idents (prefill de-dupes)
|
// Static and Self are also special idents (prefill de-dupes)
|
||||||
(super::STATIC_KEYWORD_NAME, Static, "static");
|
(super::STATIC_KEYWORD_NAME, Static, "static");
|
||||||
(super::SELF_KEYWORD_NAME, Self, "self");
|
(super::SELF_KEYWORD_NAME, Self, "self");
|
||||||
(37, Struct, "struct");
|
(38, Struct, "struct");
|
||||||
(38, Super, "super");
|
(39, Super, "super");
|
||||||
(39, True, "true");
|
(40, True, "true");
|
||||||
(40, Trait, "trait");
|
(41, Trait, "trait");
|
||||||
(41, Type, "type");
|
(42, Type, "type");
|
||||||
(42, Unsafe, "unsafe");
|
(43, Unsafe, "unsafe");
|
||||||
(43, Use, "use");
|
(44, Use, "use");
|
||||||
(44, While, "while");
|
(45, While, "while");
|
||||||
(45, Continue, "continue");
|
(46, Continue, "continue");
|
||||||
(46, Proc, "proc");
|
(47, Proc, "proc");
|
||||||
(47, Box, "box");
|
(48, Box, "box");
|
||||||
|
|
||||||
'reserved:
|
'reserved:
|
||||||
(48, Alignof, "alignof");
|
(49, Alignof, "alignof");
|
||||||
(49, Be, "be");
|
(50, Be, "be");
|
||||||
(50, Offsetof, "offsetof");
|
(51, Offsetof, "offsetof");
|
||||||
(51, Pure, "pure");
|
(52, Pure, "pure");
|
||||||
(52, Sizeof, "sizeof");
|
(53, Sizeof, "sizeof");
|
||||||
(53, Typeof, "typeof");
|
(54, Typeof, "typeof");
|
||||||
(54, Unsized, "unsized");
|
(55, Unsized, "unsized");
|
||||||
(55, Yield, "yield");
|
(56, Yield, "yield");
|
||||||
(56, Do, "do");
|
(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