Skip to content

Commit cb8ecd7

Browse files
committed
Allow extern mods to be anonymous
extern mod { f(); } is now allowed, and puts f in the enclosing scope. (Requires a link_name attribute to be really useful...)
1 parent cdcf5a7 commit cb8ecd7

File tree

8 files changed

+54
-20
lines changed

8 files changed

+54
-20
lines changed

src/libsyntax/ast.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -656,9 +656,14 @@ enum foreign_abi {
656656
foreign_abi_stdcall,
657657
}
658658

659+
// Foreign mods can be named or anonymous
660+
#[auto_serialize]
661+
enum foreign_mod_sort { named, anonymous }
662+
659663
#[auto_serialize]
660664
type foreign_mod =
661-
{view_items: ~[@view_item],
665+
{sort: foreign_mod_sort,
666+
view_items: ~[@view_item],
662667
items: ~[@foreign_item]};
663668

664669
#[auto_serialize]
@@ -775,6 +780,10 @@ type struct_def = {
775780
dtor: Option<class_dtor>
776781
};
777782

783+
/*
784+
FIXME (#3300): Should allow items to be anonymous. Right now
785+
we just use dummy names for anon items.
786+
*/
778787
#[auto_serialize]
779788
type item = {ident: ident, attrs: ~[attribute],
780789
id: node_id, node: item_,

src/libsyntax/fold.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,8 @@ fn noop_fold_mod(m: _mod, fld: ast_fold) -> _mod {
554554
}
555555

556556
fn noop_fold_foreign_mod(nm: foreign_mod, fld: ast_fold) -> foreign_mod {
557-
return {view_items: vec::map(nm.view_items, |x| fld.fold_view_item(x)),
557+
return {sort: nm.sort,
558+
view_items: vec::map(nm.view_items, |x| fld.fold_view_item(x)),
558559
items: vec::map(nm.items, |x| fld.fold_foreign_item(x))}
559560
}
560561

src/libsyntax/parse/parser.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2890,7 +2890,8 @@ struct parser {
28902890
}
28912891
}
28922892

2893-
fn parse_foreign_mod_items(+first_item_attrs: ~[attribute]) ->
2893+
fn parse_foreign_mod_items(sort: ast::foreign_mod_sort,
2894+
+first_item_attrs: ~[attribute]) ->
28942895
foreign_mod {
28952896
// Shouldn't be any view items since we've already parsed an item attr
28962897
let {attrs_remaining, view_items, items: _} =
@@ -2905,7 +2906,7 @@ struct parser {
29052906
initial_attrs = ~[];
29062907
vec::push(items, self.parse_foreign_item(attrs));
29072908
}
2908-
return {view_items: view_items,
2909+
return {sort: sort, view_items: view_items,
29092910
items: items};
29102911
}
29112912

@@ -2919,12 +2920,16 @@ struct parser {
29192920
} else {
29202921
self.expect_keyword(~"module");
29212922
}
2922-
let ident = self.parse_ident();
2923+
let (sort, ident) = match self.token {
2924+
token::IDENT(*) => (ast::named, self.parse_ident()),
2925+
_ => (ast::anonymous,
2926+
token::special_idents::clownshoes_foreign_mod)
2927+
};
29232928

29242929
// extern mod { ... }
29252930
if items_allowed && self.eat(token::LBRACE) {
29262931
let extra_attrs = self.parse_inner_attrs_and_next();
2927-
let m = self.parse_foreign_mod_items(extra_attrs.next);
2932+
let m = self.parse_foreign_mod_items(sort, extra_attrs.next);
29282933
self.expect(token::RBRACE);
29292934
return iovi_item(self.mk_item(lo, self.last_span.hi, ident,
29302935
item_foreign_mod(m), visibility,

src/libsyntax/parse/token.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ mod special_idents {
319319
const blk : ident = 30u;
320320
const static : ident = 31u;
321321
const intrinsic : ident = 32u;
322-
322+
const clownshoes_foreign_mod: ident = 33;
323323
}
324324

325325
type ident_interner = util::interner::interner<@~str>;
@@ -343,7 +343,7 @@ fn mk_ident_interner() -> ident_interner {
343343
@~"str", @~"ty_visitor", @~"arg", @~"descrim",
344344
@~"__rust_abi", @~"__rust_stack_shim", @~"tydesc",
345345
@~"dtor", @~"main", @~"<opaque>", @~"blk", @~"static",
346-
@~"intrinsic"];
346+
@~"intrinsic", @~"__foreign_mod__"];
347347

348348
let rv = interner::mk_prefill::<@~str>(|x| str::hash(*x),
349349
|x,y| str::eq(*x, *y), init_vec);

src/libsyntax/print/pprust.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,10 @@ fn print_item(s: ps, &&item: @ast::item) {
469469
ast::item_foreign_mod(nmod) => {
470470
head(s, ~"extern");
471471
word_nbsp(s, ~"mod");
472-
print_ident(s, item.ident);
472+
match nmod.sort {
473+
ast::named => print_ident(s, item.ident),
474+
ast::anonymous => {}
475+
}
473476
nbsp(s);
474477
bopen(s);
475478
print_foreign_mod(s, nmod, item.attrs);

src/rustc/front/config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ fn fold_foreign_mod(cx: ctxt, nm: ast::foreign_mod,
7575
let filtered_view_items = vec::filter_map(
7676
nm.view_items, view_item_filter);
7777
return {
78+
sort: nm.sort,
7879
view_items: vec::map(filtered_view_items, |x| fld.fold_view_item(x)),
7980
items: filtered_items
8081
};

src/rustc/middle/resolve3.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import syntax::ast::{ty_int, ty_param, ty_path, ty_str, ty_u, ty_u16, ty_u32};
4141
import syntax::ast::{ty_u64, ty_u8, ty_uint, variant, view_item};
4242
import syntax::ast::{view_item_export, view_item_import, view_item_use};
4343
import syntax::ast::{view_path_glob, view_path_list, view_path_simple};
44-
import syntax::ast::{visibility};
44+
import syntax::ast::{visibility, anonymous, named};
4545
import syntax::ast_util::{def_id_of_def, dummy_sp, local_def, new_def_hash};
4646
import syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method};
4747
import syntax::attr::{attr_metas, contains_name};
@@ -866,19 +866,25 @@ struct Resolver {
866866

867867
visit_mod(module_, sp, item.id, new_parent, visitor);
868868
}
869-
item_foreign_mod(*) => {
870-
let (name_bindings, new_parent) = self.add_child(atom, parent,
871-
~[ModuleNS], sp);
869+
item_foreign_mod(fm) => {
870+
let new_parent = match fm.sort {
871+
named => {
872+
let (name_bindings, new_parent) = self.add_child(atom,
873+
parent, ~[ModuleNS], sp);
872874

873-
let parent_link = self.get_parent_link(new_parent, atom);
874-
let def_id = { crate: 0, node: item.id };
875-
(*name_bindings).define_module(parent_link, Some(def_id),
876-
sp);
875+
let parent_link = self.get_parent_link(new_parent, atom);
876+
let def_id = { crate: 0, node: item.id };
877+
(*name_bindings).define_module(parent_link, Some(def_id),
878+
sp);
877879

878-
let new_parent =
879-
ModuleReducedGraphParent((*name_bindings).get_module());
880+
ModuleReducedGraphParent((*name_bindings).get_module())
881+
}
882+
// For anon foreign mods, the contents just go in the
883+
// current scope
884+
anonymous => parent
885+
};
880886

881-
visit_item(item, new_parent, visitor);
887+
visit_item(item, new_parent, visitor);
882888
}
883889

884890
// These items live in the value namespace.

src/test/run-pass/anon-extern-mod.rs

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+
extern mod {
4+
fn last_os_error() -> ~str;
5+
}
6+
7+
fn main() {
8+
last_os_error();
9+
}

0 commit comments

Comments
 (0)