Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Import lookup #196

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,8 @@ TEST_XFAILS_BOOT := $(TASK_XFAILS) \
test/run-pass/vec-slice.rs \
test/run-pass/while-and-do-while.rs \
test/run-fail/task-comm-14.rs \
test/compile-fail/import.rs \
test/compile-fail/import2.rs \
test/compile-fail/bad-recv.rs \
test/compile-fail/bad-send.rs \
test/compile-fail/infinite-vec-type-recursion.rs \
Expand Down Expand Up @@ -441,6 +443,7 @@ TEST_XFAILS_RUSTC := $(filter-out \
i8-incr.rs \
import2.rs \
import3.rs \
import4.rs \
item-name-overload.rs \
large-records.rs \
lazy-init.rs \
Expand Down Expand Up @@ -477,6 +480,8 @@ TEST_XFAILS_RUSTC := $(filter-out \
$(addprefix test/compile-fail/, \
arg-count-mismatch.rs \
arg-type-mismatch.rs \
import.rs \
import2.rs \
while-type-error.rs \
), \
$(wildcard test/*/*.rs test/*/*.rc))
Expand Down
97 changes: 67 additions & 30 deletions src/comp/middle/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import front.ast.ident;
import front.ast.def;
import front.ast.ann;
import driver.session;
import util.common.new_def_hash;
import util.common.span;
import std.map.hashmap;
import std.list.list;
Expand All @@ -24,6 +25,8 @@ tag scope {
type env = rec(list[scope] scopes,
session.session sess);

type import_map = std.map.hashmap[ast.def_id,def_wrap];

// A simple wrapper over defs that stores a bit more information about modules
// and uses so that we can use the regular lookup_name when resolving imports.
tag def_wrap {
Expand Down Expand Up @@ -66,31 +69,35 @@ fn unwrap_def(option.t[def_wrap] d_) -> option.t[def] {

// Follow the path of an import and return what it ultimately points to.

fn find_final_def(&env e, vec[ident] idents) -> option.t[def_wrap] {
fn find_final_def(&env e, &span sp, vec[ident] idents) -> option.t[def_wrap] {
auto len = _vec.len[ident](idents);
auto first = idents.(0);
auto d_ = lookup_name(e, none[import_map], first);
if (len == 1u) {
ret lookup_name(e, first);
ret d_;
}
auto d_ = lookup_name(e, first);
alt (d_) {
case (none[def_wrap]) {
e.sess.span_err(sp, "unresolved name: " + first);
ret d_;
}
case (some[def_wrap](?d)) {
alt(d) {
alt (d) {
case (def_wrap_mod(?i)) {
auto new_env = update_env_for_item(e, i);
auto new_idents = _vec.slice[ident](idents, 1u, len);
ret find_final_def(new_env, new_idents);
auto tmp_e = rec(scopes = nil[scope],
sess = e.sess);
auto new_e = update_env_for_item(tmp_e, i);
ret find_final_def(new_e, sp, new_idents);
}
}
}
}
fail;
}

fn lookup_name(&env e, ast.ident i) -> option.t[def_wrap] {
fn lookup_name(&env e, option.t[import_map] index,
ast.ident i) -> option.t[def_wrap] {

// log "resolving name " + i;

Expand Down Expand Up @@ -134,29 +141,33 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def_wrap] {
ret none[def_wrap];
}

fn found_def_view(&env e, @ast.view_item i) -> option.t[def_wrap] {
fn found_def_view(&env e, option.t[import_map] index,
@ast.view_item i) -> option.t[def_wrap] {
alt (i.node) {
case (ast.view_item_use(_, _, ?id)) {
ret some[def_wrap](def_wrap_use(i));
}
case (ast.view_item_import(?idents,_)) {
auto d = find_final_def(e, idents);
alt (d) {
case (some[def_wrap](_)) {
ret d;
case (ast.view_item_import(?idents,?d)) {
alt (index) {
case (some[import_map](?idx)) {
ret idx.find(d);
}
case (none[import_map]) {
ret find_final_def(e, i.span, idents);
}
}
}
}
fail;
}

fn check_mod(&env e, ast.ident i, ast._mod m) -> option.t[def_wrap] {
fn check_mod(&env e, option.t[import_map] index, ast.ident i,
ast._mod m) -> option.t[def_wrap] {
alt (m.index.find(i)) {
case (some[ast.mod_index_entry](?ent)) {
alt (ent) {
case (ast.mie_view_item(?ix)) {
ret found_def_view(e, m.view_items.(ix));
ret found_def_view(e, index, m.view_items.(ix));
}
case (ast.mie_item(?ix)) {
ret found_def_item(m.items.(ix));
Expand All @@ -182,11 +193,12 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def_wrap] {
}


fn in_scope(ast.ident i, env e, &scope s) -> option.t[def_wrap] {
fn in_scope(ast.ident i, env e, option.t[import_map] index,
&scope s) -> option.t[def_wrap] {
alt (s) {

case (scope_crate(?c)) {
ret check_mod(e, i, c.node.module);
ret check_mod(e, index, i, c.node.module);
}

case (scope_item(?it)) {
Expand Down Expand Up @@ -220,7 +232,7 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def_wrap] {
}
}
case (ast.item_mod(_, ?m, _)) {
ret check_mod(e, i, m);
ret check_mod(e, index, i, m);
}
case (_) { /* fall through */ }
}
Expand Down Expand Up @@ -248,13 +260,15 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def_wrap] {
ret none[def_wrap];
}

ret std.list.find[scope,def_wrap](e.scopes, bind in_scope(i, e, _));
ret std.list.find[scope,def_wrap](e.scopes,
bind in_scope(i, e, index, _));
}

fn fold_pat_tag(&env e, &span sp, ident i, vec[@ast.pat] args,
option.t[ast.variant_def] old_def, ann a) -> @ast.pat {
fn fold_pat_tag(&env e, &span sp, import_map index, ident i,
vec[@ast.pat] args, option.t[ast.variant_def] old_def,
ann a) -> @ast.pat {
auto new_def;
alt (unwrap_def(lookup_name(e, i))) {
alt (unwrap_def(lookup_name(e, some(index), i))) {
case (some[def](?d)) {
alt (d) {
case (ast.def_variant(?did, ?vid)) {
Expand All @@ -275,14 +289,14 @@ fn fold_pat_tag(&env e, &span sp, ident i, vec[@ast.pat] args,
ret @fold.respan[ast.pat_](sp, ast.pat_tag(i, args, new_def, a));
}

fn fold_expr_name(&env e, &span sp, &ast.name n,
&option.t[def] d, ann a) -> @ast.expr {
fn fold_expr_name(&env e, &span sp, import_map index,
&ast.name n, &option.t[def] d, ann a) -> @ast.expr {

if (_vec.len[@ast.ty](n.node.types) > 0u) {
e.sess.unimpl("resolving name expr with ty params");
}

auto d_ = unwrap_def(lookup_name(e, n.node.ident));
auto d_ = unwrap_def(lookup_name(e, some(index), n.node.ident));

alt (d_) {
case (some[def](_)) {
Expand All @@ -296,7 +310,27 @@ fn fold_expr_name(&env e, &span sp, &ast.name n,
ret @fold.respan[ast.expr_](sp, ast.expr_name(n, d_, a));
}

fn fold_ty_path(&env e, &span sp, ast.path p,
fn fold_view_item_import(&env e, &span sp,
import_map index,
vec[ident] is, ast.def_id id) -> @ast.view_item {
// Produce errors for invalid imports
auto len = _vec.len[ast.ident](is);
auto last_id = is.(len - 1u);
auto d = lookup_name(e, none[import_map], last_id);
alt (d) {
case (none[def_wrap]) {
e.sess.span_err(sp, "unresolved name: " + last_id);
}
case (some[def_wrap](?d2)) {
index.insert(id, d2);
}
}

ret @fold.respan[ast.view_item_](sp, ast.view_item_import(is, id));
}


fn fold_ty_path(&env e, &span sp, import_map index, ast.path p,
&option.t[def] d) -> @ast.ty {

let uint len = _vec.len[ast.name](p);
Expand All @@ -311,7 +345,7 @@ fn fold_ty_path(&env e, &span sp, ast.path p,
e.sess.unimpl("resolving path ty with ty params");
}

auto d_ = unwrap_def(lookup_name(e, n.node.ident));
auto d_ = unwrap_def(lookup_name(e, some(index), n.node.ident));

alt (d_) {
case (some[def](_)) {
Expand Down Expand Up @@ -345,9 +379,12 @@ fn resolve_crate(session.session sess, @ast.crate crate) -> @ast.crate {

let fold.ast_fold[env] fld = fold.new_identity_fold[env]();

fld = @rec( fold_pat_tag = bind fold_pat_tag(_,_,_,_,_,_),
fold_expr_name = bind fold_expr_name(_,_,_,_,_),
fold_ty_path = bind fold_ty_path(_,_,_,_),
auto import_index = new_def_hash[def_wrap]();
fld = @rec( fold_pat_tag = bind fold_pat_tag(_,_,import_index,_,_,_,_),
fold_expr_name = bind fold_expr_name(_,_,import_index,_,_,_),
fold_view_item_import
= bind fold_view_item_import(_,_,import_index,_,_),
fold_ty_path = bind fold_ty_path(_,_,import_index,_,_),
update_env_for_crate = bind update_env_for_crate(_,_),
update_env_for_item = bind update_env_for_item(_,_),
update_env_for_block = bind update_env_for_block(_,_),
Expand Down
11 changes: 11 additions & 0 deletions src/test/compile-fail/import.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// error-pattern: unresolved name: baz
import zed.bar;
import zed.baz;
mod zed {
fn bar() {
log "bar";
}
}
fn main(vec[str] args) {
bar();
}
12 changes: 12 additions & 0 deletions src/test/compile-fail/import2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// error-pattern: unresolved name: zed
import baz.zed.bar;
mod baz {
}
mod zed {
fn bar() {
log "bar3";
}
}
fn main(vec[str] args) {
bar();
}
10 changes: 10 additions & 0 deletions src/test/run-pass/import4.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import zed.bar;
mod zed {
fn bar() {
log "bar";
}
}
fn main(vec[str] args) {
auto zed = 42;
bar();
}
10 changes: 5 additions & 5 deletions src/test/run-pass/use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ use libc();
use zed(name = "std");
use bar(name = "std", ver = "0.0.1");

import std._str;
import x = std._str;

// FIXME: commented out since resolve doesn't know how to handle crates yet.
// import std._str;
// import x = std._str;

mod baz {
use std;
use libc();
use zed(name = "std");
use bar(name = "std", ver = "0.0.1");

import std._str;
import x = std._str;
// import std._str;
// import x = std._str;
}

fn main() {
Expand Down