Skip to content

Commit 8643f75

Browse files
committed
rustc: Fix cross-crate reexports. #3908. r=pcwalton
1 parent a5718ba commit 8643f75

File tree

5 files changed

+36
-11
lines changed

5 files changed

+36
-11
lines changed

src/librustc/metadata/csearch.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,10 @@ fn get_type_param_count(cstore: cstore::CStore, def: ast::def_id) -> uint {
6363
fn each_path(cstore: cstore::CStore, cnum: ast::crate_num,
6464
f: fn(decoder::path_entry) -> bool) {
6565
let crate_data = cstore::get_crate_data(cstore, cnum);
66-
decoder::each_path(cstore.intr, crate_data, f);
66+
let get_crate_data: decoder::GetCrateDataCb = |cnum| {
67+
cstore::get_crate_data(cstore, cnum)
68+
};
69+
decoder::each_path(cstore.intr, crate_data, get_crate_data, f);
6770
}
6871

6972
fn get_item_path(tcx: ty::ctxt, def: ast::def_id) -> ast_map::path {

src/librustc/metadata/cstore.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,11 @@ fn get_crate_vers(cstore: CStore, cnum: ast::crate_num) -> ~str {
9898
fn set_crate_data(cstore: CStore, cnum: ast::crate_num,
9999
data: crate_metadata) {
100100
p(cstore).metas.insert(cnum, data);
101-
for vec::each(decoder::get_crate_module_paths(cstore.intr, data)) |dp| {
101+
let get_crate_data: decoder::GetCrateDataCb = |cnum| {
102+
cstore::get_crate_data(cstore, cnum)
103+
};
104+
for vec::each(decoder::get_crate_module_paths(cstore.intr, data,
105+
get_crate_data)) |dp| {
102106
let (did, path) = *dp;
103107
let d = {crate: cnum, node: did.node};
104108
p(cstore).mod_path_map.insert(d, @path);

src/librustc/metadata/decoder.rs

+23-7
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export item_type; // sketchy
6060
export maybe_get_item_ast;
6161
export decode_inlined_item;
6262
export method_info, _impl;
63+
export GetCrateDataCb;
6364

6465
// Used internally by astencode:
6566
export translate_def_id;
@@ -88,6 +89,8 @@ fn lookup_hash(d: ebml::Doc, eq_fn: fn(x:&[u8]) -> bool, hash: uint) ->
8889
None
8990
}
9091

92+
pub type GetCrateDataCb = &fn(ast::crate_num) -> cmd;
93+
9194
fn maybe_find_item(item_id: int, items: ebml::Doc) -> Option<ebml::Doc> {
9295
fn eq_item(bytes: &[u8], item_id: int) -> bool {
9396
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 {
477480
}
478481

479482
/// Iterates over all the paths in the given crate.
480-
fn each_path(intr: @ident_interner, cdata: cmd, f: fn(path_entry) -> bool) {
483+
fn each_path(intr: @ident_interner, cdata: cmd,
484+
get_crate_data: GetCrateDataCb,
485+
f: fn(path_entry) -> bool) {
481486
let root = ebml::Doc(cdata.data);
482487
let items = ebml::get_doc(root, tag_items);
483488
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) {
526531
reexport_path = path + ~"::" + reexport_name;
527532
}
528533

534+
// This reexport may be in yet another crate
535+
let other_crates_items = if def_id.crate == cdata.cnum {
536+
items
537+
} else {
538+
let crate_data = get_crate_data(def_id.crate);
539+
let root = ebml::Doc(crate_data.data);
540+
ebml::get_doc(root, tag_items)
541+
};
542+
529543
// Get the item.
530-
match maybe_find_item(def_id.node, items) {
544+
match maybe_find_item(def_id.node, other_crates_items) {
531545
None => {}
532546
Some(item_doc) => {
533547
// Construct the def for this item.
@@ -1079,9 +1093,10 @@ fn get_crate_vers(data: @~[u8]) -> ~str {
10791093
};
10801094
}
10811095

1082-
fn iter_crate_items(intr: @ident_interner,
1083-
cdata: cmd, proc: fn(~str, ast::def_id)) {
1084-
for each_path(intr, cdata) |path_entry| {
1096+
fn iter_crate_items(intr: @ident_interner, cdata: cmd,
1097+
get_crate_data: GetCrateDataCb,
1098+
proc: fn(~str, ast::def_id)) {
1099+
for each_path(intr, cdata, get_crate_data) |path_entry| {
10851100
match path_entry.def_like {
10861101
dl_impl(*) | dl_field => {}
10871102
dl_def(def) => {
@@ -1091,7 +1106,8 @@ fn iter_crate_items(intr: @ident_interner,
10911106
}
10921107
}
10931108

1094-
fn get_crate_module_paths(intr: @ident_interner, cdata: cmd)
1109+
fn get_crate_module_paths(intr: @ident_interner, cdata: cmd,
1110+
get_crate_data: GetCrateDataCb)
10951111
-> ~[(ast::def_id, ~str)] {
10961112
fn mod_of_path(p: ~str) -> ~str {
10971113
str::connect(vec::init(str::split_str(p, ~"::")), ~"::")
@@ -1101,7 +1117,7 @@ fn get_crate_module_paths(intr: @ident_interner, cdata: cmd)
11011117
// fowarded path due to renamed import or reexport
11021118
let mut res = ~[];
11031119
let mods = map::HashMap();
1104-
do iter_crate_items(intr, cdata) |path, did| {
1120+
do iter_crate_items(intr, cdata, get_crate_data) |path, did| {
11051121
let m = mod_of_path(path);
11061122
if str::is_not_empty(m) {
11071123
// if m has a sub-item, it must be a module

src/librustc/middle/trans/base.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -2436,7 +2436,10 @@ fn gather_local_rtcalls(ccx: @crate_ctxt, crate: @ast::crate) {
24362436

24372437
fn gather_external_rtcalls(ccx: @crate_ctxt) {
24382438
do cstore::iter_crate_data(ccx.sess.cstore) |_cnum, cmeta| {
2439-
do decoder::each_path(ccx.sess.intr(), cmeta) |path| {
2439+
let get_crate_data: decoder::GetCrateDataCb = |cnum| {
2440+
cstore::get_crate_data(ccx.sess.cstore, cnum)
2441+
};
2442+
do decoder::each_path(ccx.sess.intr(), cmeta, get_crate_data) |path| {
24402443
let pathname = path.path_string;
24412444
match path.def_like {
24422445
decoder::dl_def(d) => {

src/test/run-pass/pub-use-xcrate.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// xfail-test Issue #3908
21
// aux-build:pub_use_xcrate1.rs
32
// aux-build:pub_use_xcrate2.rs
43

0 commit comments

Comments
 (0)