Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustc: Fix cross-crate reexports. #3908 #3943

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/librustc/metadata/csearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
6 changes: 5 additions & 1 deletion src/librustc/metadata/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
30 changes: 23 additions & 7 deletions src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<ebml::Doc> {
fn eq_item(bytes: &[u8], item_id: int) -> bool {
return io::u64_from_be_bytes(vec::view(bytes, 0u, 4u), 0u, 4u) as int
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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) => {
Expand All @@ -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, ~"::")), ~"::")
Expand All @@ -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
Expand Down
5 changes: 4 additions & 1 deletion src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
1 change: 0 additions & 1 deletion src/test/run-pass/pub-use-xcrate.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// xfail-test Issue #3908
// aux-build:pub_use_xcrate1.rs
// aux-build:pub_use_xcrate2.rs

Expand Down