Skip to content

Commit 5b9eda4

Browse files
committed
Fix the import handling in "complex" cases. When looking a.b.c and 'a' is a
module, we should look for 'b' *just* in the module 'a' and then continue resolving b.c in the environment created by updating *with* a. Still not 100% correct, but getting there.
1 parent c8a2c44 commit 5b9eda4

File tree

4 files changed

+46
-5
lines changed

4 files changed

+46
-5
lines changed

src/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ TEST_XFAILS_RUSTC := $(filter-out \
447447
import3.rs \
448448
import4.rs \
449449
import5.rs \
450+
import6.rs \
450451
item-name-overload.rs \
451452
large-records.rs \
452453
lazy-init.rs \

src/comp/middle/resolve.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ fn lookup_name(&env e, import_map index,
7777
// Follow the path of an import and return what it ultimately points to.
7878

7979
fn find_final_def(&env e, &span sp, vec[ident] idents) -> def_wrap {
80+
81+
// We are given a series of identifiers (a.b.c.d) and we know that
82+
// in the environment 'e' the identifier 'a' was resolved to 'd'. We
83+
// should return what a.b.c.d points to in the end.
8084
fn found_something(&env e, std.map.hashmap[ast.def_id, bool] pending,
8185
&span sp, vec[ident] idents, def_wrap d) -> def_wrap {
8286
alt (d) {
@@ -90,6 +94,7 @@ fn find_final_def(&env e, &span sp, vec[ident] idents) -> def_wrap {
9094
}
9195
pending.insert(d, true);
9296
auto x = inner(e, pending, sp, new_idents);
97+
pending.remove(d);
9398
ret found_something(e, pending, sp, idents, x);
9499
}
95100
}
@@ -103,11 +108,23 @@ fn find_final_def(&env e, &span sp, vec[ident] idents) -> def_wrap {
103108
}
104109
alt (d) {
105110
case (def_wrap_mod(?i)) {
106-
auto new_idents = _vec.slice[ident](idents, 1u, len);
107-
auto tmp_e = rec(scopes = nil[scope],
108-
sess = e.sess);
109-
auto new_e = update_env_for_item(tmp_e, i);
110-
ret inner(new_e, pending, sp, new_idents);
111+
auto rest_idents = _vec.slice[ident](idents, 1u, len);
112+
auto empty_e = rec(scopes = nil[scope],
113+
sess = e.sess);
114+
auto tmp_e = update_env_for_item(empty_e, i);
115+
auto next_i = rest_idents.(0);
116+
auto next_ = lookup_name_wrapped(tmp_e, next_i);
117+
alt (next_) {
118+
case (none[def_wrap]) {
119+
e.sess.span_err(sp, "unresolved name: " + next_i);
120+
fail;
121+
}
122+
case (some[def_wrap](?next)) {
123+
auto combined_e = update_env_for_item(e, i);
124+
ret found_something(combined_e, pending, sp,
125+
rest_idents, next);
126+
}
127+
}
111128
}
112129
case (def_wrap_use(?c)) {
113130
e.sess.span_err(sp, "Crate access is not implemented");

src/test/compile-fail/import4.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// error-pattern: recursive import
2+
3+
import zed.bar;
4+
import bar.zed;
5+
6+
fn main(vec[str] args) {
7+
log "loop";
8+
}

src/test/run-pass/import6.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import bar.baz;
2+
import foo.zed;
3+
mod foo {
4+
mod zed {
5+
fn baz() {
6+
log "baz";
7+
}
8+
}
9+
}
10+
mod bar {
11+
import zed.baz;
12+
}
13+
fn main(vec[str] args) {
14+
baz();
15+
}

0 commit comments

Comments
 (0)