Skip to content

Commit 578b726

Browse files
committed
rustc: Encode reexports in the metadata and don't have each_path search tag_paths
1 parent 7bae344 commit 578b726

File tree

8 files changed

+161
-67
lines changed

8 files changed

+161
-67
lines changed

src/rustc/driver/driver.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
176176

177177
let { def_map: def_map,
178178
exp_map: exp_map,
179+
exp_map2: exp_map2,
179180
impl_map: impl_map,
180181
trait_map: trait_map } =
181182
time(time_passes, ~"resolution", ||
@@ -238,7 +239,7 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
238239

239240
let (llmod, link_meta) = time(time_passes, ~"translation", ||
240241
trans::base::trans_crate(sess, crate, ty_cx, outputs.obj_filename,
241-
exp_map, maps));
242+
exp_map, exp_map2, maps));
242243

243244
time(time_passes, ~"LLVM passes", ||
244245
link::write::run_passes(sess, llmod, outputs.obj_filename));

src/rustc/metadata.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
mod middle {
66
import ty = middle_::ty;
77
export ty;
8+
import resolve3 = middle_::resolve3;
9+
export resolve3;
810
}
911

1012
mod front {

src/rustc/metadata/common.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,12 @@ const tag_paths_foreign_path: uint = 0x4a;
100100
const tag_item_trait_method_self_ty: uint = 0x4b;
101101
const tag_item_trait_method_self_ty_region: uint = 0x4c;
102102

103+
// Reexports are found within module tags. Each reexport contains def_ids
104+
// and names.
105+
const tag_items_data_item_reexport: uint = 0x4d;
106+
const tag_items_data_item_reexport_def_id: uint = 0x4e;
107+
const tag_items_data_item_reexport_name: uint = 0x4f;
108+
103109
// used to encode crate_ctxt side tables
104110
enum astencode_tag { // Reserves 0x50 -- 0x6f
105111
tag_ast = 0x50,
@@ -115,15 +121,15 @@ enum astencode_tag { // Reserves 0x50 -- 0x6f
115121
tag_table_node_type = 0x57,
116122
tag_table_node_type_subst = 0x58,
117123
tag_table_freevars = 0x59,
118-
tag_table_tcache,
119-
tag_table_param_bounds,
120-
tag_table_inferred_modes,
121-
tag_table_mutbl,
122-
tag_table_last_use,
123-
tag_table_spill,
124-
tag_table_method_map,
125-
tag_table_vtable_map,
126-
tag_table_borrowings
124+
tag_table_tcache = 0x5a,
125+
tag_table_param_bounds = 0x5b,
126+
tag_table_inferred_modes = 0x5c,
127+
tag_table_mutbl = 0x5d,
128+
tag_table_last_use = 0x5e,
129+
tag_table_spill = 0x5f,
130+
tag_table_method_map = 0x60,
131+
tag_table_vtable_map = 0x61,
132+
tag_table_borrowings = 0x62
127133
}
128134

129135
// djb's cdb hashes.

src/rustc/metadata/decoder.rs

Lines changed: 55 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,14 @@ fn item_def_id(d: ebml::doc, cdata: cmd) -> ast::def_id {
127127
|d| parse_def_id(d)));
128128
}
129129

130+
fn each_reexport(d: ebml::doc, f: fn(ebml::doc) -> bool) {
131+
for ebml::tagged_docs(d, tag_items_data_item_reexport) |reexport_doc| {
132+
if !f(reexport_doc) {
133+
return;
134+
}
135+
}
136+
}
137+
130138
fn field_mutability(d: ebml::doc) -> ast::class_mutability {
131139
// Use maybe_get_doc in case it's a method
132140
option::map_default(
@@ -426,76 +434,73 @@ fn each_path(cdata: cmd, f: fn(path_entry) -> bool) {
426434
// First, go through all the explicit items.
427435
for ebml::tagged_docs(items_data, tag_items_data_item) |item_doc| {
428436
if !broken {
429-
let name = ast_map::path_to_str_with_sep(item_path(item_doc),
437+
let path = ast_map::path_to_str_with_sep(item_path(item_doc),
430438
~"::");
431-
if name != ~"" {
439+
if path != ~"" {
432440
// Extract the def ID.
433441
let def_id = item_def_id(item_doc, cdata);
434442

435443
// Construct the def for this item.
436-
debug!{"(each_path) yielding explicit item: %s", name};
444+
debug!{"(each_path) yielding explicit item: %s", path};
437445
let def_like = item_to_def_like(item_doc, def_id, cdata.cnum);
438446

439447
// Hand the information off to the iteratee.
440-
let this_path_entry = path_entry(name, def_like);
448+
let this_path_entry = path_entry(path, def_like);
441449
if !f(this_path_entry) {
442450
broken = true; // XXX: This is awful.
443451
}
444452
}
445-
}
446-
}
447-
448-
// If broken, stop here.
449-
if broken {
450-
return;
451-
}
452-
453-
// Next, go through all the paths. We will find items that we didn't know
454-
// about before (reexports in particular).
455-
//
456-
// XXX: This is broken; the paths are actually hierarchical.
457453

458-
let outer_paths = ebml::get_doc(root, tag_paths);
459-
let inner_paths = ebml::get_doc(outer_paths, tag_paths);
460-
461-
fn g(cdata: cmd, items: ebml::doc, path_doc: ebml::doc, &broken: bool,
462-
f: fn(path_entry) -> bool) {
463-
464-
if !broken {
465-
let path = item_name(path_doc);
466-
467-
// Extract the def ID.
468-
let def_id = item_def_id(path_doc, cdata);
454+
// If this is a module, find the reexports.
455+
for each_reexport(item_doc) |reexport_doc| {
456+
if !broken {
457+
let def_id_doc =
458+
ebml::get_doc(reexport_doc,
459+
tag_items_data_item_reexport_def_id);
460+
let def_id =
461+
ebml::with_doc_data(def_id_doc, |d| parse_def_id(d));
462+
let def_id = translate_def_id(cdata, def_id);
463+
464+
let reexport_name_doc =
465+
ebml::get_doc(reexport_doc,
466+
tag_items_data_item_reexport_name);
467+
let reexport_name = ebml::doc_as_str(reexport_name_doc);
468+
469+
let reexport_path;
470+
if path == ~"" {
471+
reexport_path = reexport_name;
472+
} else {
473+
reexport_path = path + ~"::" + reexport_name;
474+
}
469475

470-
// Get the item.
471-
match maybe_find_item(def_id.node, items) {
472-
none => {
473-
debug!{"(each_path) ignoring implicit item: %s",
474-
*path};
475-
}
476-
some(item_doc) => {
477-
// Construct the def for this item.
478-
let def_like = item_to_def_like(item_doc, def_id,
479-
cdata.cnum);
480-
481-
// Hand the information off to the iteratee.
482-
debug!{"(each_path) yielding implicit item: %s",
483-
*path};
484-
let this_path_entry = path_entry(*path, def_like);
485-
if (!f(this_path_entry)) {
486-
broken = true; // XXX: This is awful.
476+
// Get the item.
477+
match maybe_find_item(def_id.node, items) {
478+
none => {}
479+
some(item_doc) => {
480+
// Construct the def for this item.
481+
let def_like = item_to_def_like(item_doc,
482+
def_id,
483+
cdata.cnum);
484+
485+
// Hand the information off to the iteratee.
486+
debug!("(each_path) yielding reexported \
487+
item: %s", reexport_path);
488+
489+
let this_path_entry =
490+
path_entry(reexport_path, def_like);
491+
if (!f(this_path_entry)) {
492+
broken = true; // XXX: This is awful.
493+
}
494+
}
487495
}
488496
}
489497
}
490498
}
491499
}
492500

493-
for ebml::tagged_docs(inner_paths, tag_paths_data_item) |path_doc| {
494-
g(cdata, items, path_doc, broken, f);
495-
}
496-
497-
for ebml::tagged_docs(inner_paths, tag_paths_foreign_path) |path_doc| {
498-
g(cdata, items, path_doc, broken, f);
501+
// If broken, stop here.
502+
if broken {
503+
return;
499504
}
500505
}
501506

src/rustc/metadata/encoder.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import syntax::ast_util::*;
1313
import common::*;
1414
import middle::ty;
1515
import middle::ty::node_id_to_type;
16+
import middle::resolve3;
1617
import syntax::ast_map;
1718
import syntax::attr;
1819
import std::serialization::serializer;
@@ -44,6 +45,7 @@ type encode_parms = {
4445
tcx: ty::ctxt,
4546
reachable: hashmap<ast::node_id, ()>,
4647
reexports: ~[(~str, def_id)],
48+
reexports2: middle::resolve3::ExportMap2,
4749
impl_map: fn@(ast::node_id) -> ~[(ident, def_id)],
4850
item_symbols: hashmap<ast::node_id, ~str>,
4951
discrim_symbols: hashmap<ast::node_id, ~str>,
@@ -57,6 +59,7 @@ enum encode_ctxt = {
5759
tcx: ty::ctxt,
5860
reachable: hashmap<ast::node_id, ()>,
5961
reexports: ~[(~str, def_id)],
62+
reexports2: middle::resolve3::ExportMap2,
6063
impl_map: fn@(ast::node_id) -> ~[(ident, def_id)],
6164
item_symbols: hashmap<ast::node_id, ~str>,
6265
discrim_symbols: hashmap<ast::node_id, ~str>,
@@ -278,7 +281,7 @@ fn encode_trait_ref(ebml_w: ebml::writer, ecx: @encode_ctxt, t: @trait_ref) {
278281
}
279282

280283
fn encode_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt, crate: @crate)
281-
-> ~[entry<~str>] {
284+
-> ~[entry<~str>] {
282285
let mut index: ~[entry<~str>] = ~[];
283286
let mut path: ~[ident] = ~[];
284287
ebml_w.start_tag(tag_paths);
@@ -478,6 +481,31 @@ fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::writer, md: _mod,
478481
} // for
479482

480483
encode_path(ebml_w, path, ast_map::path_mod(name));
484+
485+
// Encode the reexports of this module.
486+
debug!("(encoding info for module) encoding reexports for %d", id);
487+
match ecx.reexports2.find(id) {
488+
some(exports) => {
489+
debug!("(encoding info for module) found reexports for %d", id);
490+
for exports.each |exp| {
491+
debug!("(encoding info for module) reexport '%s' for %d",
492+
exp.name, id);
493+
ebml_w.start_tag(tag_items_data_item_reexport);
494+
ebml_w.start_tag(tag_items_data_item_reexport_def_id);
495+
ebml_w.wr_str(def_to_str(exp.def_id));
496+
ebml_w.end_tag();
497+
ebml_w.start_tag(tag_items_data_item_reexport_name);
498+
ebml_w.wr_str(exp.name);
499+
ebml_w.end_tag();
500+
ebml_w.end_tag();
501+
}
502+
}
503+
none => {
504+
debug!("(encoding info for module) found no reexports for %d",
505+
id);
506+
}
507+
}
508+
481509
ebml_w.end_tag();
482510
}
483511

@@ -1228,6 +1256,7 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] {
12281256
tcx: parms.tcx,
12291257
reachable: parms.reachable,
12301258
reexports: parms.reexports,
1259+
reexports2: parms.reexports2,
12311260
impl_map: parms.impl_map,
12321261
item_symbols: parms.item_symbols,
12331262
discrim_symbols: parms.discrim_symbols,

src/rustc/middle/resolve3.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,16 @@ type TraitMap = @hashmap<node_id,@DVec<def_id>>;
9696
type Export = { reexp: bool, id: def_id };
9797
type ExportMap = hashmap<node_id, ~[Export]>;
9898

99+
// This is the replacement export map. It maps a module to all of the exports
100+
// within.
101+
type ExportMap2 = hashmap<node_id, ~[Export2]>;
102+
103+
struct Export2 {
104+
name: ~str; // The name of the target.
105+
def_id: def_id; // The definition of the target.
106+
reexport: bool; // Whether this is a reexport.
107+
}
108+
99109
enum PatternBindingMode {
100110
RefutableMode,
101111
IrrefutableMode
@@ -701,6 +711,7 @@ struct Resolver {
701711
let def_map: DefMap;
702712
let impl_map: ImplMap;
703713
let export_map: ExportMap;
714+
let export_map2: ExportMap2;
704715
let trait_map: TraitMap;
705716

706717
new(session: session, lang_items: LanguageItems, crate: @crate) {
@@ -741,6 +752,7 @@ struct Resolver {
741752
self.def_map = int_hash();
742753
self.impl_map = int_hash();
743754
self.export_map = int_hash();
755+
self.export_map2 = int_hash();
744756
self.trait_map = @int_hash();
745757
}
746758

@@ -2734,6 +2746,7 @@ struct Resolver {
27342746
}
27352747

27362748
fn record_exports_for_module(module_: @Module) {
2749+
let mut exports2 = ~[];
27372750
for module_.exported_names.each |name, node_id| {
27382751
let mut exports = ~[];
27392752
for self.namespaces.each |namespace| {
@@ -2752,22 +2765,49 @@ struct Resolver {
27522765
// Nothing to do.
27532766
}
27542767
ChildNameDefinition(target_def) => {
2768+
debug!("(computing exports) found child export '%s' \
2769+
for %?",
2770+
*self.atom_table.atom_to_str(name),
2771+
module_.def_id);
27552772
vec::push(exports, {
27562773
reexp: false,
27572774
id: def_id_of_def(target_def)
27582775
});
2776+
vec::push(exports2, Export2 {
2777+
reexport: false,
2778+
name: copy *self.atom_table.atom_to_str(name),
2779+
def_id: def_id_of_def(target_def)
2780+
});
27592781
}
27602782
ImportNameDefinition(target_def) => {
2783+
debug!("(computing exports) found reexport '%s' for \
2784+
%?",
2785+
*self.atom_table.atom_to_str(name),
2786+
module_.def_id);
27612787
vec::push(exports, {
27622788
reexp: true,
27632789
id: def_id_of_def(target_def)
27642790
});
2791+
vec::push(exports2, Export2 {
2792+
reexport: true,
2793+
name: copy *self.atom_table.atom_to_str(name),
2794+
def_id: def_id_of_def(target_def)
2795+
});
27652796
}
27662797
}
27672798
}
27682799

27692800
self.export_map.insert(node_id, exports);
27702801
}
2802+
2803+
match copy module_.def_id {
2804+
some(def_id) => {
2805+
self.export_map2.insert(def_id.node, move exports2);
2806+
debug!("(computing exports) writing exports for %d (some)",
2807+
def_id.node);
2808+
}
2809+
none => {}
2810+
}
27712811
}
27722812

27732813
// Implementation scope creation
@@ -4846,6 +4886,7 @@ struct Resolver {
48464886
fn resolve_crate(session: session, lang_items: LanguageItems, crate: @crate)
48474887
-> { def_map: DefMap,
48484888
exp_map: ExportMap,
4889+
exp_map2: ExportMap2,
48494890
impl_map: ImplMap,
48504891
trait_map: TraitMap } {
48514892

@@ -4854,6 +4895,7 @@ fn resolve_crate(session: session, lang_items: LanguageItems, crate: @crate)
48544895
return {
48554896
def_map: resolver.def_map,
48564897
exp_map: resolver.export_map,
4898+
exp_map2: resolver.export_map2,
48574899
impl_map: resolver.impl_map,
48584900
trait_map: resolver.trait_map
48594901
};

0 commit comments

Comments
 (0)