Skip to content

Commit 451da07

Browse files
committed
Allow anonymous extern mods
Now you can write: extern { f() -> int; } and f will be accessible in the enclosing scope.
1 parent c491bf9 commit 451da07

File tree

4 files changed

+53
-20
lines changed

4 files changed

+53
-20
lines changed

src/libsyntax/ast_map.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,14 @@ fn map_item(i: @item, cx: ctx, v: vt) {
239239
cx.map.insert(nitem.id,
240240
node_foreign_item(nitem, abi,
241241
/* FIXME (#2543) */
242-
extend(cx, i.ident)));
242+
if nm.sort == ast::named {
243+
extend(cx, i.ident)
244+
}
245+
else {
246+
/* Anonymous extern mods go
247+
in the parent scope */
248+
@copy cx.path
249+
}));
243250
}
244251
}
245252
item_class(struct_def, _) => {

src/rustc/metadata/creader.rs

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ fn visit_view_item(e: env, i: @ast::view_item) {
109109

110110
fn visit_item(e: env, i: @ast::item) {
111111
match i.node {
112-
ast::item_foreign_mod(_) => {
112+
ast::item_foreign_mod(fm) => {
113113
match attr::foreign_abi(i.attrs) {
114114
either::Right(abi) => {
115115
if abi != ast::foreign_abi_cdecl &&
@@ -119,27 +119,36 @@ fn visit_item(e: env, i: @ast::item) {
119119
}
120120

121121
let cstore = e.cstore;
122-
let foreign_name =
123-
match attr::first_attr_value_str_by_name(i.attrs, ~"link_name") {
124-
Some(nn) => {
125-
if nn == ~"" {
126-
e.diag.span_fatal(
127-
i.span,
128-
~"empty #[link_name] not allowed; use #[nolink].");
129-
}
130-
nn
131-
}
132-
None => *e.intr.get(i.ident)
133-
};
134122
let mut already_added = false;
135-
if vec::len(attr::find_attrs_by_name(i.attrs, ~"nolink")) == 0u {
136-
already_added = !cstore::add_used_library(cstore, foreign_name);
137-
}
138123
let link_args = attr::find_attrs_by_name(i.attrs, ~"link_args");
139-
if vec::len(link_args) > 0u && already_added {
140-
e.diag.span_fatal(i.span, ~"library '" + foreign_name +
141-
~"' already added: can't specify link_args.");
124+
125+
match fm.sort {
126+
ast::named => {
127+
let foreign_name =
128+
match attr::first_attr_value_str_by_name(i.attrs,
129+
~"link_name") {
130+
Some(nn) => {
131+
if nn == ~"" {
132+
e.diag.span_fatal(
133+
i.span,
134+
~"empty #[link_name] not allowed; use #[nolink].");
135+
}
136+
nn
137+
}
138+
None => *e.intr.get(i.ident)
139+
};
140+
if attr::find_attrs_by_name(i.attrs, ~"nolink").is_empty() {
141+
already_added = !cstore::add_used_library(cstore,
142+
foreign_name);
143+
}
144+
if link_args.is_not_empty() && already_added {
145+
e.diag.span_fatal(i.span, ~"library '" + foreign_name +
146+
~"' already added: can't specify link_args.");
147+
}
148+
}
149+
ast::anonymous => { /* do nothing */ }
142150
}
151+
143152
for link_args.each |a| {
144153
match attr::get_meta_item_value_str(attr::attr_meta(a)) {
145154
Some(linkarg) => {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#[abi = "cdecl"];
2+
#[link_name = "rustrt"];
3+
#[link(name = "anonexternmod",
4+
vers = "0.1")];
5+
6+
#[crate_type = "lib"];
7+
extern {
8+
fn last_os_error() -> ~str;
9+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// aux-build:anon-extern-mod-cross-crate-1.rs
2+
use anonexternmod;
3+
4+
import anonexternmod::*;
5+
6+
fn main() {
7+
last_os_error();
8+
}

0 commit comments

Comments
 (0)