about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRafael Ávila de Espíndola <respindola@mozilla.com>2011-01-14 17:20:14 -0500
committerRafael Ávila de Espíndola <respindola@mozilla.com>2011-01-14 17:34:00 -0500
commit5b9eda4a41a410ffd8529a80c19f499ff856e07f (patch)
tree8643c5269b17344e41e66f1ee7658c39ebc2aa7d
parentc8a2c44a8e67d05204bac2850852f7fec0d23332 (diff)
downloadrust-5b9eda4a41a410ffd8529a80c19f499ff856e07f.tar.gz
rust-5b9eda4a41a410ffd8529a80c19f499ff856e07f.zip
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.
-rw-r--r--src/Makefile1
-rw-r--r--src/comp/middle/resolve.rs27
-rw-r--r--src/test/compile-fail/import4.rs8
-rw-r--r--src/test/run-pass/import6.rs15
4 files changed, 46 insertions, 5 deletions
diff --git a/src/Makefile b/src/Makefile
index 6bb40a98d4b..bf7570675f6 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -447,6 +447,7 @@ TEST_XFAILS_RUSTC := $(filter-out \
                         import3.rs \
                         import4.rs \
                         import5.rs \
+                        import6.rs \
                         item-name-overload.rs \
                         large-records.rs \
                         lazy-init.rs \
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs
index a318c779547..a8cbc468237 100644
--- a/src/comp/middle/resolve.rs
+++ b/src/comp/middle/resolve.rs
@@ -77,6 +77,10 @@ fn lookup_name(&env e, import_map index,
 // Follow the path of an import and return what it ultimately points to.
 
 fn find_final_def(&env e, &span sp, vec[ident] idents) -> def_wrap {
+
+    // We are given a series of identifiers (a.b.c.d) and we know that
+    // in the environment 'e' the identifier 'a' was resolved to 'd'. We
+    // should return what a.b.c.d points to in the end.
     fn found_something(&env e, std.map.hashmap[ast.def_id, bool] pending,
                        &span sp, vec[ident] idents, def_wrap d) -> def_wrap {
         alt (d) {
@@ -90,6 +94,7 @@ fn find_final_def(&env e, &span sp, vec[ident] idents) -> def_wrap {
                         }
                         pending.insert(d, true);
                         auto x = inner(e, pending, sp, new_idents);
+                        pending.remove(d);
                         ret found_something(e, pending, sp, idents, x);
                     }
                 }
@@ -103,11 +108,23 @@ fn find_final_def(&env e, &span sp, vec[ident] idents) -> def_wrap {
         }
         alt (d) {
             case (def_wrap_mod(?i)) {
-                auto new_idents = _vec.slice[ident](idents, 1u, len);
-                auto tmp_e = rec(scopes = nil[scope],
-                                 sess = e.sess);
-                auto new_e = update_env_for_item(tmp_e, i);
-                ret inner(new_e, pending, sp, new_idents);
+                auto rest_idents = _vec.slice[ident](idents, 1u, len);
+                auto empty_e = rec(scopes = nil[scope],
+                                   sess = e.sess);
+                auto tmp_e = update_env_for_item(empty_e, i);
+                auto next_i = rest_idents.(0);
+                auto next_ = lookup_name_wrapped(tmp_e, next_i);
+                alt (next_) {
+                    case (none[def_wrap]) {
+                        e.sess.span_err(sp, "unresolved name: " + next_i);
+                        fail;
+                    }
+                    case (some[def_wrap](?next)) {
+                        auto combined_e = update_env_for_item(e, i);
+                        ret found_something(combined_e, pending, sp,
+                                            rest_idents, next);
+                    }
+                }
             }
             case (def_wrap_use(?c)) {
                 e.sess.span_err(sp, "Crate access is not implemented");
diff --git a/src/test/compile-fail/import4.rs b/src/test/compile-fail/import4.rs
new file mode 100644
index 00000000000..f769d6d3966
--- /dev/null
+++ b/src/test/compile-fail/import4.rs
@@ -0,0 +1,8 @@
+// error-pattern: recursive import
+
+import zed.bar;
+import bar.zed;
+
+fn main(vec[str] args) {
+  log "loop";
+}
diff --git a/src/test/run-pass/import6.rs b/src/test/run-pass/import6.rs
new file mode 100644
index 00000000000..5e3a9d7429a
--- /dev/null
+++ b/src/test/run-pass/import6.rs
@@ -0,0 +1,15 @@
+import bar.baz;
+import foo.zed;
+mod foo {
+  mod zed {
+    fn baz() {
+      log "baz";
+    }
+  }
+}
+mod bar {
+  import zed.baz;
+}
+fn main(vec[str] args) {
+  baz();
+}