mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-26 06:35:27 +00:00
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...)
This commit is contained in:
parent
cdcf5a7580
commit
cb8ecd7984
@ -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_,
|
||||
|
@ -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))}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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.
|
||||
|
9
src/test/run-pass/anon-extern-mod.rs
Normal file
9
src/test/run-pass/anon-extern-mod.rs
Normal file
@ -0,0 +1,9 @@
|
||||
#[abi = "cdecl"]
|
||||
#[link_name = "rustrt"]
|
||||
extern mod {
|
||||
fn last_os_error() -> ~str;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
last_os_error();
|
||||
}
|
Loading…
Reference in New Issue
Block a user