mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-20 03:32:52 +00:00
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.
This commit is contained in:
parent
3c61793b5a
commit
2fb09eb585
@ -437,6 +437,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 \
|
||||
|
@ -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_];
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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](_)) {
|
||||
|
9
src/test/run-pass/import2.rs
Normal file
9
src/test/run-pass/import2.rs
Normal file
@ -0,0 +1,9 @@
|
||||
import zed.bar;
|
||||
mod zed {
|
||||
fn bar() {
|
||||
log "bar";
|
||||
}
|
||||
}
|
||||
fn main(vec[str] args) {
|
||||
bar();
|
||||
}
|
12
src/test/run-pass/import3.rs
Normal file
12
src/test/run-pass/import3.rs
Normal file
@ -0,0 +1,12 @@
|
||||
import zed.bar;
|
||||
import baz.zed;
|
||||
mod baz {
|
||||
mod zed {
|
||||
fn bar() {
|
||||
log "bar2";
|
||||
}
|
||||
}
|
||||
}
|
||||
fn main(vec[str] args) {
|
||||
bar();
|
||||
}
|
Loading…
Reference in New Issue
Block a user