Skip to content

Commit 14fcb13

Browse files
committed
Improve resolution of impls
Issue #1227
1 parent 7efef98 commit 14fcb13

File tree

1 file changed

+33
-18
lines changed

1 file changed

+33
-18
lines changed

src/comp/middle/resolve.rs

+33-18
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import syntax::{ast, ast_util, codemap};
33
import syntax::ast::*;
44
import ast::{ident, fn_ident, def, def_id, node_id};
5-
import syntax::ast_util::{local_def, def_id_of_def};
5+
import syntax::ast_util::{local_def, def_id_of_def, is_exported};
66

77
import metadata::{csearch, cstore};
88
import driver::session::session;
@@ -494,7 +494,8 @@ fn resolve_import(e: env, defid: ast::def_id, name: ast::ident,
494494
impls: [@ast::item]) {
495495
let val = lookup(ns_value), typ = lookup(ns_type),
496496
md = lookup(ns_module);
497-
if is_none(val) && is_none(typ) && is_none(md) {
497+
if is_none(val) && is_none(typ) && is_none(md) &&
498+
vec::len(impls) == 0u {
498499
unresolved_err(e, cx, sp, name, "import");
499500
} else {
500501
e.imports.insert(id, resolved(val, typ, md, @impls, name, sp));
@@ -1112,7 +1113,7 @@ fn lookup_in_local_native_mod(e: env, node_id: node_id, sp: span, id: ident,
11121113
fn lookup_in_local_mod(e: env, node_id: node_id, sp: span, id: ident,
11131114
ns: namespace, dr: dir) -> option::t<def> {
11141115
let info = e.mod_map.get(node_id);
1115-
if dr == outside && !ast_util::is_exported(id, option::get(info.m)) {
1116+
if dr == outside && !is_exported(id, option::get(info.m)) {
11161117
// if we're in a native mod, then dr==inside, so info.m is some _mod
11171118
ret none::<def>; // name is not visible
11181119
}
@@ -1637,12 +1638,22 @@ fn resolve_impls(e: @env, c: @ast::crate) {
16371638
}
16381639

16391640
fn find_impls_in_view_item(e: env, vi: @ast::view_item,
1640-
&impls: [@ast::item]) {
1641+
&impls: [@ast::item], sc: iscopes) {
16411642
alt vi.node {
1642-
ast::view_item_import(ident, _, id) {
1643-
// FIXME if single name, simply look in our own iscope
1644-
alt e.imports.get(id) {
1645-
resolved(_, _, _, is, _, _) { impls += *is; }
1643+
ast::view_item_import(_, pt, id) {
1644+
let found = [];
1645+
if vec::len(*pt) == 1u {
1646+
list::iter(sc) {|level|
1647+
if vec::len(found) > 0u { ret; }
1648+
for imp in *level {
1649+
if imp.ident == pt[0] { found += [imp]; }
1650+
}
1651+
if vec::len(found) > 0u { impls += found; }
1652+
}
1653+
} else {
1654+
alt e.imports.get(id) {
1655+
resolved(_, _, _, is, _, _) { impls += *is; }
1656+
}
16461657
}
16471658
}
16481659
ast::view_item_import_from(base, names, _) {
@@ -1667,26 +1678,28 @@ fn find_impls_in_view_item(e: env, vi: @ast::view_item,
16671678
}
16681679

16691680
fn find_impls_in_item(i: @ast::item, &impls: [@ast::item],
1670-
name: option::t<ident>, _dir: dir) {
1671-
// FIXME check exports
1681+
name: option::t<ident>,
1682+
ck_exports: option::t<ast::_mod>) {
16721683
alt i.node {
16731684
ast::item_impl(_, _, _) {
1674-
if alt name { some(n) { n == i.ident } _ { true } } {
1685+
if alt name { some(n) { n == i.ident } _ { true } } &&
1686+
alt ck_exports { some(m) { is_exported(i.ident, m) } _ { true } } {
16751687
impls += [i];
16761688
}
16771689
}
16781690
_ {}
16791691
}
16801692
}
16811693

1694+
// FIXME[impl] external importing of impls
16821695
fn find_impls_in_mod(e: env, m: def, &impls: [@ast::item],
16831696
name: option::t<ident>) {
16841697
alt m {
16851698
ast::def_mod(defid) {
1686-
// FIXME external importing of impls
16871699
if defid.crate == ast::local_crate {
1688-
for i in option::get(e.mod_map.get(defid.node).m).items {
1689-
find_impls_in_item(i, impls, name, outside);
1700+
let md = option::get(e.mod_map.get(defid.node).m);
1701+
for i in md.items {
1702+
find_impls_in_item(i, impls, name, some(md));
16901703
}
16911704
}
16921705
}
@@ -1699,11 +1712,13 @@ type iscopes = list<@[@ast::item]>;
16991712
fn visit_block_with_impl_scope(e: @env, b: ast::blk, sc: iscopes,
17001713
v: vt<iscopes>) {
17011714
let impls = [];
1702-
for vi in b.node.view_items { find_impls_in_view_item(*e, vi, impls); }
1715+
for vi in b.node.view_items {
1716+
find_impls_in_view_item(*e, vi, impls, sc);
1717+
}
17031718
for st in b.node.stmts {
17041719
alt st.node {
17051720
ast::stmt_decl(@{node: ast::decl_item(i), _}, _) {
1706-
find_impls_in_item(i, impls, none, inside);
1721+
find_impls_in_item(i, impls, none, none);
17071722
}
17081723
_ {}
17091724
}
@@ -1715,8 +1730,8 @@ fn visit_block_with_impl_scope(e: @env, b: ast::blk, sc: iscopes,
17151730
fn visit_mod_with_impl_scope(e: @env, m: ast::_mod, s: span, sc: iscopes,
17161731
v: vt<iscopes>) {
17171732
let impls = [];
1718-
for vi in m.view_items { find_impls_in_view_item(*e, vi, impls); }
1719-
for i in m.items { find_impls_in_item(i, impls, none, inside); }
1733+
for vi in m.view_items { find_impls_in_view_item(*e, vi, impls, sc); }
1734+
for i in m.items { find_impls_in_item(i, impls, none, none); }
17201735
visit::visit_mod(m, s, vec::len(impls) > 0u ? cons(@impls, @sc) : sc, v);
17211736
}
17221737

0 commit comments

Comments
 (0)