From 9212da6cd93e5b6bba6b81d679bd14b57a77b098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20=C3=81vila=20de=20Esp=C3=ADndola?= Date: Fri, 7 Jan 2011 17:38:13 -0500 Subject: [PATCH] Add sufficient import support to compile some simple single-crate programs. This is likely not the final solution. It does repetitive work and doesn't produce errors for invalid but unused imports. In any case, I think it is a useful step. --- src/Makefile | 2 + src/comp/front/ast.rs | 1 - src/comp/middle/fold.rs | 8 +- src/comp/middle/resolve.rs | 143 +++++++++++++++++++++++++++-------- src/test/run-pass/import2.rs | 9 +++ src/test/run-pass/import3.rs | 12 +++ 6 files changed, 138 insertions(+), 37 deletions(-) create mode 100644 src/test/run-pass/import2.rs create mode 100644 src/test/run-pass/import3.rs diff --git a/src/Makefile b/src/Makefile index c407403c8fc1b..2d02a37e3107b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -436,6 +436,8 @@ TEST_XFAILS_RUSTC := $(filter-out \ int.rs \ i32-sub.rs \ i8-incr.rs \ + import2.rs \ + import3.rs \ item-name-overload.rs \ large-records.rs \ lazy-init.rs \ diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index fff7b24ca9349..5dc0c4d2916cc 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -36,7 +36,6 @@ tag def { def_ty_arg(def_id); def_binding(def_id); def_use(def_id); - def_import(def_id); } type crate = spanned[crate_]; diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs index 70f6e47012a8b..6679fc5f3443b 100644 --- a/src/comp/middle/fold.rs +++ b/src/comp/middle/fold.rs @@ -781,14 +781,14 @@ fn fold_mod[ENV](&ENV e, ast_fold[ENV] fld, &ast._mod m) -> ast._mod { let vec[@item] items = vec(); auto index = m.index; - for (@item i in m.items) { - append[@item](items, fold_item[ENV](e, fld, i)); - } - for (@view_item vi in m.view_items) { append[@view_item](view_items, fold_view_item[ENV](e, fld, vi)); } + for (@item i in m.items) { + append[@item](items, fold_item[ENV](e, fld, i)); + } + ret fld.fold_mod(e, rec(view_items=view_items, items=items, index=index)); } diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index e1f58b5d7319d..808637e748c1d 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -24,39 +24,106 @@ tag scope { type env = rec(list[scope] scopes, session.session sess); -fn lookup_name(&env e, ast.ident i) -> option.t[def] { +// 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 { + def_wrap_use(@ast.view_item); + def_wrap_mod(@ast.item); + def_wrap_other(def); +} + +fn unwrap_def(option.t[def_wrap] d_) -> option.t[def] { + alt (d_) { + case (none[def_wrap]) { + ret none[def]; + } + case (some[def_wrap](?d)) { + alt (d) { + case (def_wrap_use(?it)) { + alt (it.node) { + case (ast.view_item_use(_, _, ?id)) { + ret some[def](ast.def_use(id)); + } + } + fail; + } + case (def_wrap_mod(?i)) { + alt (i.node) { + case (ast.item_mod(_, _, ?id)) { + ret some[def](ast.def_mod(id)); + } + } + fail; + } + case (def_wrap_other(?d)) { + ret some[def](d); + } + } + } + } + fail; +} + +// 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] { + auto len = _vec.len[ident](idents); + auto first = idents.(0); + if (len == 1u) { + ret lookup_name(e, first); + } + auto d_ = lookup_name(e, first); + alt (d_) { + case (none[def_wrap]) { + ret d_; + } + case (some[def_wrap](?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); + } + } + } + } + fail; +} + +fn lookup_name(&env e, ast.ident i) -> option.t[def_wrap] { // log "resolving name " + i; - fn found_def_item(@ast.item i) -> option.t[def] { + fn found_def_item(@ast.item i) -> option.t[def_wrap] { alt (i.node) { case (ast.item_const(_, _, _, ?id, _)) { - ret some[def](ast.def_const(id)); + ret some[def_wrap](def_wrap_other(ast.def_const(id))); } case (ast.item_fn(_, _, _, ?id, _)) { - ret some[def](ast.def_fn(id)); + ret some[def_wrap](def_wrap_other(ast.def_fn(id))); } case (ast.item_mod(_, _, ?id)) { - ret some[def](ast.def_mod(id)); + ret some[def_wrap](def_wrap_mod(i)); } case (ast.item_ty(_, _, _, ?id, _)) { - ret some[def](ast.def_ty(id)); + ret some[def_wrap](def_wrap_other(ast.def_ty(id))); } case (ast.item_tag(_, _, _, ?id)) { - ret some[def](ast.def_ty(id)); + ret some[def_wrap](def_wrap_other(ast.def_ty(id))); } case (ast.item_obj(_, _, _, ?id, _)) { - ret some[def](ast.def_obj(id)); + ret some[def_wrap](def_wrap_other(ast.def_obj(id))); } } } - fn found_decl_stmt(@ast.stmt s) -> option.t[def] { + fn found_decl_stmt(@ast.stmt s) -> option.t[def_wrap] { alt (s.node) { case (ast.stmt_decl(?d)) { alt (d.node) { case (ast.decl_local(?loc)) { - ret some[def](ast.def_local(loc.id)); + auto t = ast.def_local(loc.id); + ret some[def_wrap](def_wrap_other(t)); } case (ast.decl_item(?it)) { ret found_def_item(it); @@ -64,26 +131,32 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def] { } } } - ret none[def]; + ret none[def_wrap]; } - fn found_def_view(@ast.view_item i) -> option.t[def] { + fn found_def_view(&env e, @ast.view_item i) -> option.t[def_wrap] { alt (i.node) { case (ast.view_item_use(_, _, ?id)) { - ret some[def](ast.def_use(id)); + ret some[def_wrap](def_wrap_use(i)); } - case (ast.view_item_import(_,?id)) { - ret some[def](ast.def_import(id)); + case (ast.view_item_import(?idents,_)) { + auto d = find_final_def(e, idents); + alt (d) { + case (some[def_wrap](_)) { + ret d; + } + } } } + fail; } - fn check_mod(ast.ident i, ast._mod m) -> option.t[def] { + fn check_mod(&env e, 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(m.view_items.(ix)); + ret found_def_view(e, m.view_items.(ix)); } case (ast.mie_item(?ix)) { ret found_def_item(m.items.(ix)); @@ -92,7 +165,8 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def] { alt (m.items.(item_idx).node) { case (ast.item_tag(_, ?variants, _, ?tid)) { auto vid = variants.(variant_idx).id; - ret some[def](ast.def_variant(tid, vid)); + auto t = ast.def_variant(tid, vid); + ret some[def_wrap](def_wrap_other(t)); } case (_) { log "tag item not actually a tag"; @@ -104,15 +178,15 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def] { } case (none[ast.mod_index_entry]) { /* fall through */ } } - ret none[def]; + ret none[def_wrap]; } - fn in_scope(ast.ident i, &scope s) -> option.t[def] { + fn in_scope(ast.ident i, env e, &scope s) -> option.t[def_wrap] { alt (s) { case (scope_crate(?c)) { - ret check_mod(i, c.node.module); + ret check_mod(e, i, c.node.module); } case (scope_item(?it)) { @@ -120,29 +194,33 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def] { case (ast.item_fn(_, ?f, ?ty_params, _, _)) { for (ast.arg a in f.inputs) { if (_str.eq(a.ident, i)) { - ret some[def](ast.def_arg(a.id)); + auto t = ast.def_arg(a.id); + ret some[def_wrap](def_wrap_other(t)); } } for (ast.ty_param tp in ty_params) { if (_str.eq(tp.ident, i)) { - ret some[def](ast.def_ty_arg(tp.id)); + auto t = ast.def_ty_arg(tp.id); + ret some[def_wrap](def_wrap_other(t)); } } } case (ast.item_obj(_, ?ob, ?ty_params, _, _)) { for (ast.obj_field f in ob.fields) { if (_str.eq(f.ident, i)) { - ret some[def](ast.def_obj_field(f.id)); + auto t = ast.def_obj_field(f.id); + ret some[def_wrap](def_wrap_other(t)); } } for (ast.ty_param tp in ty_params) { if (_str.eq(tp.ident, i)) { - ret some[def](ast.def_ty_arg(tp.id)); + auto t = ast.def_ty_arg(tp.id); + ret some[def_wrap](def_wrap_other(t)); } } } case (ast.item_mod(_, ?m, _)) { - ret check_mod(i, m); + ret check_mod(e, i, m); } case (_) { /* fall through */ } } @@ -160,22 +238,23 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def] { case (scope_arm(?a)) { alt (a.index.find(i)) { case (some[ast.def_id](?did)) { - ret some[def](ast.def_binding(did)); + auto t = ast.def_binding(did); + ret some[def_wrap](def_wrap_other(t)); } case (_) { /* fall through */ } } } } - ret none[def]; + ret none[def_wrap]; } - ret std.list.find[scope,def](e.scopes, bind in_scope(i, _)); + ret std.list.find[scope,def_wrap](e.scopes, bind in_scope(i, e, _)); } 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 { auto new_def; - alt (lookup_name(e, i)) { + alt (unwrap_def(lookup_name(e, i))) { case (some[def](?d)) { alt (d) { case (ast.def_variant(?did, ?vid)) { @@ -203,7 +282,7 @@ fn fold_expr_name(&env e, &span sp, &ast.name n, e.sess.unimpl("resolving name expr with ty params"); } - auto d_ = lookup_name(e, n.node.ident); + auto d_ = unwrap_def(lookup_name(e, n.node.ident)); alt (d_) { case (some[def](_)) { @@ -232,7 +311,7 @@ fn fold_ty_path(&env e, &span sp, ast.path p, e.sess.unimpl("resolving path ty with ty params"); } - auto d_ = lookup_name(e, n.node.ident); + auto d_ = unwrap_def(lookup_name(e, n.node.ident)); alt (d_) { case (some[def](_)) { diff --git a/src/test/run-pass/import2.rs b/src/test/run-pass/import2.rs new file mode 100644 index 0000000000000..31b49aeab1847 --- /dev/null +++ b/src/test/run-pass/import2.rs @@ -0,0 +1,9 @@ +import zed.bar; +mod zed { + fn bar() { + log "bar"; + } +} +fn main(vec[str] args) { + bar(); +} diff --git a/src/test/run-pass/import3.rs b/src/test/run-pass/import3.rs new file mode 100644 index 0000000000000..559c6ee9ea97c --- /dev/null +++ b/src/test/run-pass/import3.rs @@ -0,0 +1,12 @@ +import zed.bar; +import baz.zed; +mod baz { + mod zed { + fn bar() { + log "bar2"; + } + } +} +fn main(vec[str] args) { + bar(); +}