about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libsyntax/ast.rs11
-rw-r--r--src/libsyntax/fold.rs3
-rw-r--r--src/libsyntax/parse/parser.rs13
-rw-r--r--src/libsyntax/parse/token.rs4
-rw-r--r--src/libsyntax/print/pprust.rs5
-rw-r--r--src/rustc/front/config.rs1
-rw-r--r--src/rustc/middle/resolve3.rs28
-rw-r--r--src/test/run-pass/anon-extern-mod.rs9
8 files changed, 54 insertions, 20 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index a9df28abeba..b04a55629d2 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -656,9 +656,14 @@ enum foreign_abi {
     foreign_abi_stdcall,
 }
 
+// Foreign mods can be named or anonymous
+#[auto_serialize]
+enum foreign_mod_sort { named, anonymous }
+
 #[auto_serialize]
 type foreign_mod =
-    {view_items: ~[@view_item],
+    {sort: foreign_mod_sort,
+     view_items: ~[@view_item],
      items: ~[@foreign_item]};
 
 #[auto_serialize]
@@ -775,6 +780,10 @@ type struct_def = {
     dtor: Option<class_dtor>
 };
 
+/*
+  FIXME (#3300): Should allow items to be anonymous. Right now
+  we just use dummy names for anon items.
+ */
 #[auto_serialize]
 type item = {ident: ident, attrs: ~[attribute],
              id: node_id, node: item_,
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 2006ccf639c..7375eb49aed 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -554,7 +554,8 @@ fn noop_fold_mod(m: _mod, fld: ast_fold) -> _mod {
 }
 
 fn noop_fold_foreign_mod(nm: foreign_mod, fld: ast_fold) -> foreign_mod {
-    return {view_items: vec::map(nm.view_items, |x| fld.fold_view_item(x)),
+    return {sort: nm.sort,
+         view_items: vec::map(nm.view_items, |x| fld.fold_view_item(x)),
          items: vec::map(nm.items, |x| fld.fold_foreign_item(x))}
 }
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 8bc78a53548..f9a9a8261e9 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2890,7 +2890,8 @@ struct parser {
         }
     }
 
-    fn parse_foreign_mod_items(+first_item_attrs: ~[attribute]) ->
+    fn parse_foreign_mod_items(sort: ast::foreign_mod_sort,
+                               +first_item_attrs: ~[attribute]) ->
         foreign_mod {
         // Shouldn't be any view items since we've already parsed an item attr
         let {attrs_remaining, view_items, items: _} =
@@ -2905,7 +2906,7 @@ struct parser {
             initial_attrs = ~[];
             vec::push(items, self.parse_foreign_item(attrs));
         }
-        return {view_items: view_items,
+        return {sort: sort, view_items: view_items,
              items: items};
     }
 
@@ -2919,12 +2920,16 @@ struct parser {
         } else {
             self.expect_keyword(~"module");
         }
-        let ident = self.parse_ident();
+        let (sort, ident) = match self.token {
+                token::IDENT(*) => (ast::named, self.parse_ident()),
+                _ => (ast::anonymous,
+                      token::special_idents::clownshoes_foreign_mod)
+        };
 
         // extern mod { ... }
         if items_allowed && self.eat(token::LBRACE) {
             let extra_attrs = self.parse_inner_attrs_and_next();
-            let m = self.parse_foreign_mod_items(extra_attrs.next);
+            let m = self.parse_foreign_mod_items(sort, extra_attrs.next);
             self.expect(token::RBRACE);
             return iovi_item(self.mk_item(lo, self.last_span.hi, ident,
                                           item_foreign_mod(m), visibility,
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 846a7e7c88e..ae1c829b3fb 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -319,7 +319,7 @@ mod special_idents {
     const blk : ident = 30u;
     const static : ident = 31u;
     const intrinsic : ident = 32u;
-
+    const clownshoes_foreign_mod: ident = 33;
 }
 
 type ident_interner = util::interner::interner<@~str>;
@@ -343,7 +343,7 @@ fn mk_ident_interner() -> ident_interner {
                      @~"str", @~"ty_visitor", @~"arg", @~"descrim",
                      @~"__rust_abi", @~"__rust_stack_shim", @~"tydesc",
                      @~"dtor", @~"main", @~"<opaque>", @~"blk", @~"static",
-                     @~"intrinsic"];
+                     @~"intrinsic", @~"__foreign_mod__"];
 
     let rv = interner::mk_prefill::<@~str>(|x| str::hash(*x),
                                            |x,y| str::eq(*x, *y), init_vec);
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 3465ca20565..f24226d9edc 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -469,7 +469,10 @@ fn print_item(s: ps, &&item: @ast::item) {
       ast::item_foreign_mod(nmod) => {
         head(s, ~"extern");
         word_nbsp(s, ~"mod");
-        print_ident(s, item.ident);
+        match nmod.sort {
+            ast::named => print_ident(s, item.ident),
+            ast::anonymous => {}
+        }
         nbsp(s);
         bopen(s);
         print_foreign_mod(s, nmod, item.attrs);
diff --git a/src/rustc/front/config.rs b/src/rustc/front/config.rs
index 9c0f30468fc..50ed5f6132c 100644
--- a/src/rustc/front/config.rs
+++ b/src/rustc/front/config.rs
@@ -75,6 +75,7 @@ fn fold_foreign_mod(cx: ctxt, nm: ast::foreign_mod,
     let filtered_view_items = vec::filter_map(
         nm.view_items, view_item_filter);
     return {
+        sort: nm.sort,
         view_items: vec::map(filtered_view_items, |x| fld.fold_view_item(x)),
         items: filtered_items
     };
diff --git a/src/rustc/middle/resolve3.rs b/src/rustc/middle/resolve3.rs
index 1115e92a9de..33260e1fe6f 100644
--- a/src/rustc/middle/resolve3.rs
+++ b/src/rustc/middle/resolve3.rs
@@ -41,7 +41,7 @@ import syntax::ast::{ty_int, ty_param, ty_path, ty_str, ty_u, ty_u16, ty_u32};
 import syntax::ast::{ty_u64, ty_u8, ty_uint, variant, view_item};
 import syntax::ast::{view_item_export, view_item_import, view_item_use};
 import syntax::ast::{view_path_glob, view_path_list, view_path_simple};
-import syntax::ast::{visibility};
+import syntax::ast::{visibility, anonymous, named};
 import syntax::ast_util::{def_id_of_def, dummy_sp, local_def, new_def_hash};
 import syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method};
 import syntax::attr::{attr_metas, contains_name};
@@ -866,19 +866,25 @@ struct Resolver {
 
                 visit_mod(module_, sp, item.id, new_parent, visitor);
             }
-            item_foreign_mod(*) => {
-              let (name_bindings, new_parent) = self.add_child(atom, parent,
-                                                           ~[ModuleNS], sp);
+            item_foreign_mod(fm) => {
+              let new_parent = match fm.sort {
+                named => {
+                  let (name_bindings, new_parent) = self.add_child(atom,
+                     parent, ~[ModuleNS], sp);
 
-                let parent_link = self.get_parent_link(new_parent, atom);
-                let def_id = { crate: 0, node: item.id };
-                (*name_bindings).define_module(parent_link, Some(def_id),
-                                               sp);
+                  let parent_link = self.get_parent_link(new_parent, atom);
+                  let def_id = { crate: 0, node: item.id };
+                  (*name_bindings).define_module(parent_link, Some(def_id),
+                                                 sp);
 
-                let new_parent =
-                    ModuleReducedGraphParent((*name_bindings).get_module());
+                  ModuleReducedGraphParent((*name_bindings).get_module())
+                }
+                // For anon foreign mods, the contents just go in the
+                // current scope
+                anonymous => parent
+              };
 
-                visit_item(item, new_parent, visitor);
+              visit_item(item, new_parent, visitor);
             }
 
             // These items live in the value namespace.
diff --git a/src/test/run-pass/anon-extern-mod.rs b/src/test/run-pass/anon-extern-mod.rs
new file mode 100644
index 00000000000..168a3ccc59b
--- /dev/null
+++ b/src/test/run-pass/anon-extern-mod.rs
@@ -0,0 +1,9 @@
+#[abi = "cdecl"]
+#[link_name = "rustrt"]
+extern mod {
+  fn last_os_error() -> ~str;
+}
+
+fn main() {
+  last_os_error();
+}
\ No newline at end of file