From 6361661126e979a72e4716ea379746969f6aa9db Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 8 Nov 2012 16:52:21 -0800 Subject: [PATCH] rustc: Fix cross-crate reexports. #3908 --- src/librustc/metadata/csearch.rs | 5 ++++- src/librustc/metadata/cstore.rs | 6 +++++- src/librustc/metadata/decoder.rs | 30 ++++++++++++++++++++++------- src/librustc/middle/trans/base.rs | 5 ++++- src/test/run-pass/pub-use-xcrate.rs | 1 - 5 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index bbc324fbdff4c..f2387ec367b1a 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -63,7 +63,10 @@ fn get_type_param_count(cstore: cstore::CStore, def: ast::def_id) -> uint { fn each_path(cstore: cstore::CStore, cnum: ast::crate_num, f: fn(decoder::path_entry) -> bool) { let crate_data = cstore::get_crate_data(cstore, cnum); - decoder::each_path(cstore.intr, crate_data, f); + let get_crate_data: decoder::GetCrateDataCb = |cnum| { + cstore::get_crate_data(cstore, cnum) + }; + decoder::each_path(cstore.intr, crate_data, get_crate_data, f); } fn get_item_path(tcx: ty::ctxt, def: ast::def_id) -> ast_map::path { diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 6db3982297e55..911d0080449b8 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -98,7 +98,11 @@ fn get_crate_vers(cstore: CStore, cnum: ast::crate_num) -> ~str { fn set_crate_data(cstore: CStore, cnum: ast::crate_num, data: crate_metadata) { p(cstore).metas.insert(cnum, data); - for vec::each(decoder::get_crate_module_paths(cstore.intr, data)) |dp| { + let get_crate_data: decoder::GetCrateDataCb = |cnum| { + cstore::get_crate_data(cstore, cnum) + }; + for vec::each(decoder::get_crate_module_paths(cstore.intr, data, + get_crate_data)) |dp| { let (did, path) = *dp; let d = {crate: cnum, node: did.node}; p(cstore).mod_path_map.insert(d, @path); diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index bc6a8da96b89a..91648a948378c 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -60,6 +60,7 @@ export item_type; // sketchy export maybe_get_item_ast; export decode_inlined_item; export method_info, _impl; +export GetCrateDataCb; // Used internally by astencode: export translate_def_id; @@ -88,6 +89,8 @@ fn lookup_hash(d: ebml::Doc, eq_fn: fn(x:&[u8]) -> bool, hash: uint) -> None } +pub type GetCrateDataCb = &fn(ast::crate_num) -> cmd; + fn maybe_find_item(item_id: int, items: ebml::Doc) -> Option { fn eq_item(bytes: &[u8], item_id: int) -> bool { return io::u64_from_be_bytes(vec::view(bytes, 0u, 4u), 0u, 4u) as int @@ -477,7 +480,9 @@ fn path_entry(path_string: ~str, def_like: def_like) -> path_entry { } /// Iterates over all the paths in the given crate. -fn each_path(intr: @ident_interner, cdata: cmd, f: fn(path_entry) -> bool) { +fn each_path(intr: @ident_interner, cdata: cmd, + get_crate_data: GetCrateDataCb, + f: fn(path_entry) -> bool) { let root = ebml::Doc(cdata.data); let items = ebml::get_doc(root, tag_items); let items_data = ebml::get_doc(items, tag_items_data); @@ -526,8 +531,17 @@ fn each_path(intr: @ident_interner, cdata: cmd, f: fn(path_entry) -> bool) { reexport_path = path + ~"::" + reexport_name; } + // This reexport may be in yet another crate + let other_crates_items = if def_id.crate == cdata.cnum { + items + } else { + let crate_data = get_crate_data(def_id.crate); + let root = ebml::Doc(crate_data.data); + ebml::get_doc(root, tag_items) + }; + // Get the item. - match maybe_find_item(def_id.node, items) { + match maybe_find_item(def_id.node, other_crates_items) { None => {} Some(item_doc) => { // Construct the def for this item. @@ -1079,9 +1093,10 @@ fn get_crate_vers(data: @~[u8]) -> ~str { }; } -fn iter_crate_items(intr: @ident_interner, - cdata: cmd, proc: fn(~str, ast::def_id)) { - for each_path(intr, cdata) |path_entry| { +fn iter_crate_items(intr: @ident_interner, cdata: cmd, + get_crate_data: GetCrateDataCb, + proc: fn(~str, ast::def_id)) { + for each_path(intr, cdata, get_crate_data) |path_entry| { match path_entry.def_like { dl_impl(*) | dl_field => {} dl_def(def) => { @@ -1091,7 +1106,8 @@ fn iter_crate_items(intr: @ident_interner, } } -fn get_crate_module_paths(intr: @ident_interner, cdata: cmd) +fn get_crate_module_paths(intr: @ident_interner, cdata: cmd, + get_crate_data: GetCrateDataCb) -> ~[(ast::def_id, ~str)] { fn mod_of_path(p: ~str) -> ~str { str::connect(vec::init(str::split_str(p, ~"::")), ~"::") @@ -1101,7 +1117,7 @@ fn get_crate_module_paths(intr: @ident_interner, cdata: cmd) // fowarded path due to renamed import or reexport let mut res = ~[]; let mods = map::HashMap(); - do iter_crate_items(intr, cdata) |path, did| { + do iter_crate_items(intr, cdata, get_crate_data) |path, did| { let m = mod_of_path(path); if str::is_not_empty(m) { // if m has a sub-item, it must be a module diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index a2d74dc92dfd6..ba34a234a1029 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2422,7 +2422,10 @@ fn gather_local_rtcalls(ccx: @crate_ctxt, crate: @ast::crate) { fn gather_external_rtcalls(ccx: @crate_ctxt) { do cstore::iter_crate_data(ccx.sess.cstore) |_cnum, cmeta| { - do decoder::each_path(ccx.sess.intr(), cmeta) |path| { + let get_crate_data: decoder::GetCrateDataCb = |cnum| { + cstore::get_crate_data(ccx.sess.cstore, cnum) + }; + do decoder::each_path(ccx.sess.intr(), cmeta, get_crate_data) |path| { let pathname = path.path_string; match path.def_like { decoder::dl_def(d) => { diff --git a/src/test/run-pass/pub-use-xcrate.rs b/src/test/run-pass/pub-use-xcrate.rs index a425ae10087a0..3b39daa1e32b9 100644 --- a/src/test/run-pass/pub-use-xcrate.rs +++ b/src/test/run-pass/pub-use-xcrate.rs @@ -1,4 +1,3 @@ -// xfail-test Issue #3908 // aux-build:pub_use_xcrate1.rs // aux-build:pub_use_xcrate2.rs