diff --git a/src/comp/front/creader.rs b/src/comp/front/creader.rs index 3b95b24fc8f..35d10422a45 100644 --- a/src/comp/front/creader.rs +++ b/src/comp/front/creader.rs @@ -540,18 +540,15 @@ fn read_crates(session.session sess, // Crate metadata queries -fn lookup_def(session.session sess, &span sp, int cnum, vec[ast.ident] path) - -> ast.def { +fn lookup_def(session.session sess, int cnum, vec[ast.ident] path) + -> option.t[ast.def] { auto data = sess.get_external_crate(cnum); auto did; alt (resolve_path(path, data)) { case (rr_ok(?di)) { did = di; } case (rr_not_found(?prev, ?name)) { - sess.span_err(sp, - #fmt("unbound name '%s' (no item named '%s' found in '%s')", - _str.connect(path, "."), name, _str.connect(prev, "."))); - fail; + ret none[ast.def]; } } @@ -561,21 +558,24 @@ fn lookup_def(session.session sess, &span sp, int cnum, vec[ast.ident] path) did = tup(cnum, did._1); // FIXME: It'd be great if we had u8 char literals. - if (kind_ch == ('c' as u8)) { ret ast.def_const(did); } - else if (kind_ch == ('f' as u8)) { ret ast.def_fn(did); } - else if (kind_ch == ('y' as u8)) { ret ast.def_ty(did); } - else if (kind_ch == ('o' as u8)) { ret ast.def_obj(did); } - else if (kind_ch == ('t' as u8)) { ret ast.def_ty(did); } - else if (kind_ch == ('m' as u8)) { ret ast.def_mod(did); } - else if (kind_ch == ('n' as u8)) { ret ast.def_native_mod(did); } + auto def; + if (kind_ch == ('c' as u8)) { def = ast.def_const(did); } + else if (kind_ch == ('f' as u8)) { def = ast.def_fn(did); } + else if (kind_ch == ('y' as u8)) { def = ast.def_ty(did); } + else if (kind_ch == ('o' as u8)) { def = ast.def_obj(did); } + else if (kind_ch == ('t' as u8)) { def = ast.def_ty(did); } + else if (kind_ch == ('m' as u8)) { def = ast.def_mod(did); } + else if (kind_ch == ('n' as u8)) { def = ast.def_native_mod(did); } else if (kind_ch == ('v' as u8)) { auto tid = get_variant_tag_id(ebml_r); tid = tup(cnum, tid._1); - ret ast.def_variant(tid, did); + def = ast.def_variant(tid, did); + } else { + log #fmt("lookup_def(): unknown kind char: %d", kind_ch as int); + fail; } - log #fmt("lookup_def(): unknown kind char: %d", kind_ch as int); - fail; + ret some[ast.def](def); } fn get_type(session.session sess, ast.def_id def) -> ty.ty_params_and_ty { diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index 820687caea9..e171a6006b5 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -20,6 +20,7 @@ scope_crate(@ast.crate); scope_item(@ast.item); scope_native_item(@ast.native_item); + scope_external_mod(ast.def_id, vec[ast.ident]); scope_loop(@ast.decl); // there's only 1 decl per loop. scope_block(ast.block); scope_arm(ast.arm); @@ -37,6 +38,8 @@ def_wrap_import(@ast.view_item); def_wrap_mod(@ast.item); def_wrap_native_mod(@ast.item); + def_wrap_external_mod(ast.def_id); + def_wrap_external_native_mod(ast.def_id); def_wrap_other(def); def_wrap_expr_field(uint, def); def_wrap_resolving; @@ -79,6 +82,12 @@ fn unwrap_def(def_wrap d) -> def { } } } + case (def_wrap_external_mod(?mod_id)) { + ret ast.def_mod(mod_id); + } + case (def_wrap_external_native_mod(?mod_id)) { + ret ast.def_native_mod(mod_id); + } case (def_wrap_other(?d)) { ret d; } @@ -100,6 +109,30 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def] { } } +fn lookup_external_def(session.session sess, int cnum, vec[ident] idents) + -> option.t[def_wrap] { + alt (creader.lookup_def(sess, cnum, idents)) { + case (none[ast.def]) { + ret none[def_wrap]; + } + case (some[ast.def](?def)) { + auto dw; + alt (def) { + case (ast.def_mod(?mod_id)) { + dw = def_wrap_external_mod(mod_id); + } + case (ast.def_native_mod(?mod_id)) { + dw = def_wrap_external_native_mod(mod_id); + } + case (_) { + dw = def_wrap_other(def); + } + } + ret some[def_wrap](dw); + } + } +} + // Follow the path of an import and return what it ultimately points to. // If used after imports are resolved, import_id is none. @@ -136,12 +169,43 @@ fn found_mod(&env e, &import_map index, &span sp, } } + // TODO: Refactor with above. + fn found_external_mod(&env e, &import_map index, &span sp, + vec[ident] idents, ast.def_id mod_id) + -> def_wrap { + auto len = _vec.len[ident](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_external_mod(empty_e, mod_id, idents); + auto next_i = rest_idents.(0); + auto next_ = lookup_name_wrapped(tmp_e, next_i); + alt (next_) { + case (none[tup(@env, def_wrap)]) { + e.sess.span_err(sp, "unresolved name: " + next_i); + fail; + } + case (some[tup(@env, def_wrap)](?next)) { + auto combined_e = update_env_for_external_mod(e, + mod_id, + idents); + ret found_something(combined_e, index, sp, + rest_idents, next._1); + } + } + } + fn found_crate(&env e, &import_map index, &span sp, vec[ident] idents, int cnum) -> def_wrap { auto len = _vec.len[ident](idents); auto rest_idents = _vec.slice[ident](idents, 1u, len); - auto def = creader.lookup_def(e.sess, sp, cnum, rest_idents); - ret def_wrap_other(def); + alt (lookup_external_def(e.sess, cnum, rest_idents)) { + case (none[def_wrap]) { + e.sess.span_err(sp, #fmt("unbound name '%s'", + _str.connect(idents, "."))); + fail; + } + case (some[def_wrap](?dw)) { ret dw; } + } } alt (d) { @@ -168,6 +232,12 @@ fn found_crate(&env e, &import_map index, &span sp, case (def_wrap_native_mod(?i)) { ret found_mod(e, index, sp, idents, i); } + case (def_wrap_external_mod(?mod_id)) { + ret found_external_mod(e, index, sp, idents, mod_id); + } + case (def_wrap_external_native_mod(?mod_id)) { + ret found_external_mod(e, index, sp, idents, mod_id); + } case (def_wrap_use(?vi)) { alt (vi.node) { case (ast.view_item_use(_, _, _, ?cnum_opt)) { @@ -390,7 +460,8 @@ fn check_block(ast.ident i, &ast.block_ b) -> option.t[def_wrap] { } } - fn in_scope(ast.ident i, &scope s) -> option.t[def_wrap] { + fn in_scope(&session.session sess, ast.ident i, &scope s) + -> option.t[def_wrap] { alt (s) { case (scope_crate(?c)) { @@ -450,6 +521,10 @@ fn in_scope(ast.ident i, &scope s) -> option.t[def_wrap] { } } + case (scope_external_mod(?mod_id, ?path)) { + ret lookup_external_def(sess, mod_id._0, path); + } + case (scope_loop(?d)) { alt (d.node) { case (ast.decl_local(?local)) { @@ -483,7 +558,7 @@ fn in_scope(ast.ident i, &scope s) -> option.t[def_wrap] { ret none[tup(@env, def_wrap)]; } case (cons[scope](?hd, ?tl)) { - auto x = in_scope(i, hd); + auto x = in_scope(e.sess, i, hd); alt (x) { case (some[def_wrap](?x)) { ret some(tup(@e, x)); @@ -613,6 +688,15 @@ fn update_env_for_native_item(&env e, @ast.native_item i) -> env { ret rec(scopes = cons[scope](scope_native_item(i), @e.scopes) with e); } +// Not actually called by fold, but here since this is analogous to +// update_env_for_item() above and is called by find_final_def(). +fn update_env_for_external_mod(&env e, ast.def_id mod_id, + vec[ast.ident] idents) -> env { + ret rec(scopes = cons[scope](scope_external_mod(mod_id, idents), + @e.scopes) + with e); +} + fn update_env_for_block(&env e, &ast.block b) -> env { ret rec(scopes = cons[scope](scope_block(b), @e.scopes) with e); }