Skip to content

Commit c590bde

Browse files
committed
Make re-exporting of impls work
Closes #1438
1 parent 6bead0e commit c590bde

File tree

6 files changed

+135
-111
lines changed

6 files changed

+135
-111
lines changed

src/comp/driver/driver.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
199199
time(time_passes, "translation",
200200
bind trans::trans_crate(sess, crate, ty_cx,
201201
outputs.obj_filename, exp_map, ast_map,
202-
mut_map, copy_map, last_uses,
202+
mut_map, copy_map, last_uses, impl_map,
203203
method_map, dict_map));
204204
time(time_passes, "LLVM passes",
205205
bind link::write::run_passes(sess, llmod, outputs.obj_filename));

src/comp/metadata/encoder.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Metadata encoding
22

3-
import std::{io, ebml, map};
3+
import std::{io, ebml, map, list};
44
import io::writer_util;
55
import syntax::ast::*;
66
import syntax::ast_util;
@@ -151,13 +151,14 @@ fn encode_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt, crate: @crate)
151151

152152
fn encode_reexport_paths(ebml_w: ebml::writer,
153153
ecx: @encode_ctxt, &index: [entry<str>]) {
154-
ecx.ccx.exp_map.items {|key, def|
155-
let path = key.path;
156-
index += [{val: path, pos: ebml_w.writer.tell()}];
157-
ebml::start_tag(ebml_w, tag_paths_data_item);
158-
encode_name(ebml_w, path);
159-
encode_def_id(ebml_w, ast_util::def_id_of_def(def));
160-
ebml::end_tag(ebml_w);
154+
ecx.ccx.exp_map.items {|path, defs|
155+
for def in *defs {
156+
index += [{val: path, pos: ebml_w.writer.tell()}];
157+
ebml::start_tag(ebml_w, tag_paths_data_item);
158+
encode_name(ebml_w, path);
159+
encode_def_id(ebml_w, ast_util::def_id_of_def(def));
160+
ebml::end_tag(ebml_w);
161+
}
161162
}
162163
}
163164

@@ -258,23 +259,22 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer,
258259
}
259260
}
260261

261-
fn encode_info_for_mod(ebml_w: ebml::writer, md: _mod,
262+
fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::writer, md: _mod,
262263
id: node_id, name: ident) {
263264
ebml::start_tag(ebml_w, tag_items_data_item);
264265
encode_def_id(ebml_w, local_def(id));
265266
encode_family(ebml_w, 'm' as u8);
266267
encode_name(ebml_w, name);
267-
for i in md.items {
268-
alt i.node {
269-
item_impl(_, _, _, _) {
268+
alt ecx.ccx.impl_map.get(id) {
269+
list::cons(impls, @list::nil) {
270+
for i in *impls {
270271
if ast_util::is_exported(i.ident, md) {
271272
ebml::start_tag(ebml_w, tag_mod_impl);
272-
ebml_w.writer.write(str::bytes(def_to_str(local_def(i.id))));
273+
ebml_w.writer.write(str::bytes(def_to_str(i.did)));
273274
ebml::end_tag(ebml_w);
274275
}
275-
}
276-
_ {}
277276
}
277+
}
278278
}
279279
ebml::end_tag(ebml_w);
280280
}
@@ -306,7 +306,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
306306
ebml::end_tag(ebml_w);
307307
}
308308
item_mod(m) {
309-
encode_info_for_mod(ebml_w, m, item.id, item.ident);
309+
encode_info_for_mod(ecx, ebml_w, m, item.id, item.ident);
310310
}
311311
item_native_mod(_) {
312312
ebml::start_tag(ebml_w, tag_items_data_item);
@@ -447,7 +447,7 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer,
447447
let index: [entry<int>] = [];
448448
ebml::start_tag(ebml_w, tag_items_data);
449449
index += [{val: crate_node_id, pos: ebml_w.writer.tell()}];
450-
encode_info_for_mod(ebml_w, crate_mod, crate_node_id, "");
450+
encode_info_for_mod(ecx, ebml_w, crate_mod, crate_node_id, "");
451451
ecx.ccx.ast_map.items {|key, val|
452452
alt val {
453453
middle::ast_map::node_item(i) {

src/comp/middle/resolve.rs

Lines changed: 101 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -82,22 +82,6 @@ fn new_ext_hash() -> ext_hash {
8282
ret std::map::mk_hashmap::<key, def>(hash, eq);
8383
}
8484

85-
fn new_exp_hash() -> exp_map {
86-
type key = {path: str, ns: namespace};
87-
fn hash(v: key) -> uint {
88-
ret str::hash(v.path) +
89-
alt v.ns {
90-
ns_val(_) { 1u }
91-
ns_type { 2u }
92-
ns_module { 3u }
93-
};
94-
}
95-
fn eq(v1: key, v2: key) -> bool {
96-
ret str::eq(v1.path, v2.path) && v1.ns == v2.ns;
97-
}
98-
ret std::map::mk_hashmap::<key, def>(hash, eq);
99-
}
100-
10185
enum mod_index_entry {
10286
mie_view_item(@ast::view_item),
10387
mie_import_ident(node_id, codemap::span),
@@ -125,9 +109,9 @@ type indexed_mod = {
125109

126110
type def_map = hashmap<node_id, def>;
127111
type ext_map = hashmap<def_id, [ident]>;
128-
type exp_map = hashmap<{path: str, ns: namespace}, def>;
112+
type exp_map = hashmap<str, @mutable [def]>;
129113
type impl_map = hashmap<node_id, iscopes>;
130-
type impl_cache = hashmap<def_id, @[@_impl]>;
114+
type impl_cache = hashmap<def_id, option::t<@[@_impl]>>;
131115

132116
type env =
133117
{cstore: cstore::cstore,
@@ -168,7 +152,7 @@ fn resolve_crate(sess: session, amap: ast_map::map, crate: @ast::crate) ->
168152
def_map: new_int_hash(),
169153
ast_map: amap,
170154
imports: new_int_hash(),
171-
exp_map: new_exp_hash(),
155+
exp_map: new_str_hash(),
172156
mod_map: new_int_hash(),
173157
block_map: new_int_hash(),
174158
ext_map: new_def_hash(),
@@ -1725,41 +1709,50 @@ fn check_exports(e: @env) {
17251709
let (m, v, t) = (lookup(ns_module),
17261710
lookup(ns_val(ns_any_value)),
17271711
lookup(ns_type));
1728-
maybe_add_reexport(e, path + ident, ns_module, m);
1729-
maybe_add_reexport(e, path + ident, ns_val(ns_any_value), v);
1730-
maybe_add_reexport(e, path + ident, ns_type, t);
1731-
ret is_some(m) || is_some(v) || is_some(t);
1732-
}
1733-
1734-
fn maybe_add_reexport(e: @env, path: str, ns: namespace,
1735-
def: option::t<def>) {
1736-
if option::is_some(def) {
1737-
e.exp_map.insert({path: path, ns: ns}, option::get(def));
1712+
let full_path = path + ident;
1713+
maybe_add_reexport(e, full_path, m);
1714+
maybe_add_reexport(e, full_path, v);
1715+
maybe_add_reexport(e, full_path, t);
1716+
is_some(m) || is_some(v) || is_some(t)
1717+
}
1718+
1719+
fn maybe_add_reexport(e: @env, path: str, def: option::t<def>) {
1720+
alt def {
1721+
some(def) {
1722+
alt e.exp_map.find(path) {
1723+
some(v) { *v += [def]; }
1724+
none { e.exp_map.insert(path, @mutable [def]); }
1725+
}
1726+
}
1727+
_ {}
17381728
}
17391729
}
17401730

1741-
fn check_export(e: @env, ident: str, val: @indexed_mod, vi: @view_item) {
1731+
fn check_export(e: @env, ident: str, val: @indexed_mod,
1732+
vi: @view_item) {
1733+
let found_something = false;
1734+
let full_path = val.path + ident;
17421735
if val.index.contains_key(ident) {
1736+
found_something = true;
17431737
let xs = val.index.get(ident);
17441738
list::iter(xs) {|x|
17451739
alt x {
17461740
mie_import_ident(id, _) {
17471741
alt e.imports.get(id) {
17481742
resolved(v, t, m, _, rid, _) {
1749-
maybe_add_reexport(e, val.path + rid,
1750-
ns_val(ns_any_value), v);
1751-
maybe_add_reexport(e, val.path + rid, ns_type, t);
1752-
maybe_add_reexport(e, val.path + rid, ns_module, m);
1743+
maybe_add_reexport(e, full_path, v);
1744+
maybe_add_reexport(e, full_path, t);
1745+
maybe_add_reexport(e, full_path, m);
17531746
}
17541747
_ { }
17551748
}
17561749
}
17571750
_ { }
17581751
}
17591752
}
1760-
} else if lookup_glob_any(e, val, vi.span, val.path, ident) {
1761-
// do nothing
1762-
} else {
1753+
}
1754+
found_something |= lookup_glob_any(e, val, vi.span, val.path, ident);
1755+
if !found_something {
17631756
e.sess.span_warn(vi.span,
17641757
#fmt("exported item %s is not defined", ident));
17651758
}
@@ -1849,40 +1842,52 @@ type iscopes = list<@[@_impl]>;
18491842
fn resolve_impls(e: @env, c: @ast::crate) {
18501843
visit::visit_crate(*c, nil, visit::mk_vt(@{
18511844
visit_block: bind visit_block_with_impl_scope(e, _, _, _),
1852-
visit_mod: bind visit_mod_with_impl_scope(e, _, _, _, _),
1845+
visit_mod: bind visit_mod_with_impl_scope(e, _, _, _, _, _),
18531846
visit_expr: bind resolve_impl_in_expr(e, _, _, _)
18541847
with *visit::default_visitor()
18551848
}));
18561849
}
18571850

18581851
fn find_impls_in_view_item(e: env, vi: @ast::view_item,
1859-
&impls: [@_impl], sc: iscopes) {
1852+
&impls: [@_impl], sc: option::t<iscopes>) {
1853+
fn lookup_imported_impls(e: env, id: ast::node_id,
1854+
act: fn(@[@_impl])) {
1855+
alt e.imports.get(id) {
1856+
resolved(_, _, _, is, _, _) { act(is); }
1857+
todo(node_id, name, path, span, scopes) {
1858+
resolve_import(e, local_def(node_id), name, *path, span,
1859+
scopes);
1860+
alt e.imports.get(id) {
1861+
resolved(_, _, _, is, _, _) { act(is); }
1862+
}
1863+
}
1864+
_ {}
1865+
}
1866+
}
18601867
alt vi.node {
18611868
ast::view_item_import(name, pt, id) {
18621869
let found = [];
18631870
if vec::len(*pt) == 1u {
1864-
list::iter(sc) {|level|
1865-
if vec::len(found) > 0u { ret; }
1866-
for imp in *level {
1867-
if imp.ident == pt[0] {
1868-
found += [@{ident: name with *imp}];
1871+
option::may(sc) {|sc|
1872+
list::iter(sc) {|level|
1873+
if vec::len(found) > 0u { ret; }
1874+
for imp in *level {
1875+
if imp.ident == pt[0] {
1876+
found += [@{ident: name with *imp}];
1877+
}
18691878
}
1879+
if vec::len(found) > 0u { impls += found; }
18701880
}
1871-
if vec::len(found) > 0u { impls += found; }
18721881
}
18731882
} else {
1874-
alt e.imports.get(id) {
1875-
resolved(_, _, _, is, _, _) {
1883+
lookup_imported_impls(e, id) {|is|
18761884
for i in *is { impls += [@{ident: name with *i}]; }
1877-
}
18781885
}
18791886
}
18801887
}
18811888
ast::view_item_import_from(base, names, _) {
18821889
for nm in names {
1883-
alt e.imports.get(nm.node.id) {
1884-
resolved(_, _, _, is, _, _) { impls += *is; }
1885-
}
1890+
lookup_imported_impls(e, nm.node.id) {|is| impls += *is; }
18861891
}
18871892
}
18881893
ast::view_item_import_glob(ids, id) {
@@ -1922,34 +1927,45 @@ fn find_impls_in_item(e: env, i: @ast::item, &impls: [@_impl],
19221927
}
19231928
}
19241929

1930+
fn find_impls_in_mod_by_id(e: env, defid: def_id, &impls: [@_impl],
1931+
name: option::t<ident>) {
1932+
let cached;
1933+
alt e.impl_cache.find(defid) {
1934+
some(some(v)) { cached = v; }
1935+
some(none) { ret; }
1936+
none {
1937+
e.impl_cache.insert(defid, none);
1938+
cached = if defid.crate == ast::local_crate {
1939+
let tmp = [];
1940+
let md = option::get(e.mod_map.get(defid.node).m);
1941+
for vi in md.view_items {
1942+
find_impls_in_view_item(e, vi, tmp, none);
1943+
}
1944+
for i in md.items {
1945+
find_impls_in_item(e, i, tmp, none, none);
1946+
}
1947+
@vec::filter(tmp) {|i| is_exported(e, i.ident, md)}
1948+
} else {
1949+
csearch::get_impls_for_mod(e.sess.cstore, defid, none)
1950+
};
1951+
e.impl_cache.insert(defid, some(cached));
1952+
}
1953+
}
1954+
alt name {
1955+
some(n) {
1956+
for im in *cached {
1957+
if n == im.ident { impls += [im]; }
1958+
}
1959+
}
1960+
_ { impls += *cached; }
1961+
}
1962+
}
1963+
19251964
fn find_impls_in_mod(e: env, m: def, &impls: [@_impl],
19261965
name: option::t<ident>) {
19271966
alt m {
19281967
ast::def_mod(defid) {
1929-
let cached;
1930-
alt e.impl_cache.find(defid) {
1931-
some(v) { cached = v; }
1932-
none {
1933-
cached = if defid.crate == ast::local_crate {
1934-
let tmp = [];
1935-
for i in option::get(e.mod_map.get(defid.node).m).items {
1936-
find_impls_in_item(e, i, tmp, none, none);
1937-
}
1938-
@tmp
1939-
} else {
1940-
csearch::get_impls_for_mod(e.sess.cstore, defid, none)
1941-
};
1942-
e.impl_cache.insert(defid, cached);
1943-
}
1944-
}
1945-
alt name {
1946-
some(n) {
1947-
for im in *cached {
1948-
if n == im.ident { impls += [im]; }
1949-
}
1950-
}
1951-
_ { impls += *cached; }
1952-
}
1968+
find_impls_in_mod_by_id(e, defid, impls, name);
19531969
}
19541970
_ {}
19551971
}
@@ -1959,7 +1975,7 @@ fn visit_block_with_impl_scope(e: @env, b: ast::blk, sc: iscopes,
19591975
v: vt<iscopes>) {
19601976
let impls = [];
19611977
for vi in b.node.view_items {
1962-
find_impls_in_view_item(*e, vi, impls, sc);
1978+
find_impls_in_view_item(*e, vi, impls, some(sc));
19631979
}
19641980
for st in b.node.stmts {
19651981
alt st.node {
@@ -1973,12 +1989,17 @@ fn visit_block_with_impl_scope(e: @env, b: ast::blk, sc: iscopes,
19731989
visit::visit_block(b, sc, v);
19741990
}
19751991

1976-
fn visit_mod_with_impl_scope(e: @env, m: ast::_mod, s: span, sc: iscopes,
1977-
v: vt<iscopes>) {
1992+
fn visit_mod_with_impl_scope(e: @env, m: ast::_mod, s: span, id: node_id,
1993+
sc: iscopes, v: vt<iscopes>) {
19781994
let impls = [];
1979-
for vi in m.view_items { find_impls_in_view_item(*e, vi, impls, sc); }
1995+
for vi in m.view_items {
1996+
find_impls_in_view_item(*e, vi, impls, some(sc));
1997+
}
19801998
for i in m.items { find_impls_in_item(*e, i, impls, none, none); }
1981-
visit::visit_mod(m, s, vec::len(impls) > 0u ? cons(@impls, @sc) : sc, v);
1999+
let impls = @impls;
2000+
visit::visit_mod(m, s, id,
2001+
vec::len(*impls) > 0u ? cons(impls, @sc) : sc, v);
2002+
e.impl_map.insert(id, cons(impls, @nil));
19822003
}
19832004

19842005
fn resolve_impl_in_expr(e: @env, x: @ast::expr, sc: iscopes, v: vt<iscopes>) {

src/comp/middle/trans.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5498,8 +5498,8 @@ fn write_abi_version(ccx: @crate_ctxt) {
54985498
fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
54995499
output: str, emap: resolve::exp_map, amap: ast_map::map,
55005500
mut_map: mut::mut_map, copy_map: alias::copy_map,
5501-
last_uses: last_use::last_uses, method_map: typeck::method_map,
5502-
dict_map: typeck::dict_map)
5501+
last_uses: last_use::last_uses, impl_map: resolve::impl_map,
5502+
method_map: typeck::method_map, dict_map: typeck::dict_map)
55035503
-> (ModuleRef, link::link_meta) {
55045504
let sha = std::sha1::mk_sha1();
55055505
let link_meta = link::build_link_meta(sess, *crate, output, sha);
@@ -5576,6 +5576,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
55765576
mut_map: mut_map,
55775577
copy_map: copy_map,
55785578
last_uses: last_uses,
5579+
impl_map: impl_map,
55795580
method_map: method_map,
55805581
dict_map: dict_map,
55815582
stats:

src/comp/middle/trans_common.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ type crate_ctxt =
108108
mut_map: mut::mut_map,
109109
copy_map: alias::copy_map,
110110
last_uses: last_use::last_uses,
111+
impl_map: resolve::impl_map,
111112
method_map: typeck::method_map,
112113
dict_map: typeck::dict_map,
113114
stats: stats,

0 commit comments

Comments
 (0)