From 451da077188002f7db62051f973d1ee6069dd1dc Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 4 Sep 2012 16:40:11 -0700 Subject: [PATCH] Allow anonymous extern mods Now you can write: extern { f() -> int; } and f will be accessible in the enclosing scope. --- src/libsyntax/ast_map.rs | 9 +++- src/rustc/metadata/creader.rs | 47 +++++++++++-------- .../anon-extern-mod-cross-crate-1.rs | 9 ++++ .../run-pass/anon-extern-mod-cross-crate-2.rs | 8 ++++ 4 files changed, 53 insertions(+), 20 deletions(-) create mode 100644 src/test/auxiliary/anon-extern-mod-cross-crate-1.rs create mode 100644 src/test/run-pass/anon-extern-mod-cross-crate-2.rs diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 4ea7156116b8..c131c7d57ad0 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -239,7 +239,14 @@ fn map_item(i: @item, cx: ctx, v: vt) { cx.map.insert(nitem.id, node_foreign_item(nitem, abi, /* FIXME (#2543) */ - extend(cx, i.ident))); + if nm.sort == ast::named { + extend(cx, i.ident) + } + else { + /* Anonymous extern mods go + in the parent scope */ + @copy cx.path + })); } } item_class(struct_def, _) => { diff --git a/src/rustc/metadata/creader.rs b/src/rustc/metadata/creader.rs index 362220d06e86..444662ae0e2a 100644 --- a/src/rustc/metadata/creader.rs +++ b/src/rustc/metadata/creader.rs @@ -109,7 +109,7 @@ fn visit_view_item(e: env, i: @ast::view_item) { fn visit_item(e: env, i: @ast::item) { match i.node { - ast::item_foreign_mod(_) => { + ast::item_foreign_mod(fm) => { match attr::foreign_abi(i.attrs) { either::Right(abi) => { if abi != ast::foreign_abi_cdecl && @@ -119,27 +119,36 @@ fn visit_item(e: env, i: @ast::item) { } let cstore = e.cstore; - let foreign_name = - match attr::first_attr_value_str_by_name(i.attrs, ~"link_name") { - Some(nn) => { - if nn == ~"" { - e.diag.span_fatal( - i.span, - ~"empty #[link_name] not allowed; use #[nolink]."); - } - nn - } - None => *e.intr.get(i.ident) - }; let mut already_added = false; - if vec::len(attr::find_attrs_by_name(i.attrs, ~"nolink")) == 0u { - already_added = !cstore::add_used_library(cstore, foreign_name); - } let link_args = attr::find_attrs_by_name(i.attrs, ~"link_args"); - if vec::len(link_args) > 0u && already_added { - e.diag.span_fatal(i.span, ~"library '" + foreign_name + - ~"' already added: can't specify link_args."); + + match fm.sort { + ast::named => { + let foreign_name = + match attr::first_attr_value_str_by_name(i.attrs, + ~"link_name") { + Some(nn) => { + if nn == ~"" { + e.diag.span_fatal( + i.span, + ~"empty #[link_name] not allowed; use #[nolink]."); + } + nn + } + None => *e.intr.get(i.ident) + }; + if attr::find_attrs_by_name(i.attrs, ~"nolink").is_empty() { + already_added = !cstore::add_used_library(cstore, + foreign_name); + } + if link_args.is_not_empty() && already_added { + e.diag.span_fatal(i.span, ~"library '" + foreign_name + + ~"' already added: can't specify link_args."); + } + } + ast::anonymous => { /* do nothing */ } } + for link_args.each |a| { match attr::get_meta_item_value_str(attr::attr_meta(a)) { Some(linkarg) => { diff --git a/src/test/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/auxiliary/anon-extern-mod-cross-crate-1.rs new file mode 100644 index 000000000000..b1eb013bd6b4 --- /dev/null +++ b/src/test/auxiliary/anon-extern-mod-cross-crate-1.rs @@ -0,0 +1,9 @@ +#[abi = "cdecl"]; +#[link_name = "rustrt"]; +#[link(name = "anonexternmod", + vers = "0.1")]; + +#[crate_type = "lib"]; +extern { + fn last_os_error() -> ~str; +} diff --git a/src/test/run-pass/anon-extern-mod-cross-crate-2.rs b/src/test/run-pass/anon-extern-mod-cross-crate-2.rs new file mode 100644 index 000000000000..559749c95733 --- /dev/null +++ b/src/test/run-pass/anon-extern-mod-cross-crate-2.rs @@ -0,0 +1,8 @@ +// aux-build:anon-extern-mod-cross-crate-1.rs +use anonexternmod; + +import anonexternmod::*; + +fn main() { + last_os_error(); +}