aboutsummaryrefslogtreecommitdiff
path: root/src/comp
diff options
context:
space:
mode:
authorMarijn Haverbeke <[email protected]>2011-05-09 12:40:09 +0200
committerMarijn Haverbeke <[email protected]>2011-05-11 12:32:37 +0200
commite9c12ab1d019b42e5427e31bfa49f1f799e84165 (patch)
tree7f7ce69c7619060559d2da99fb78fa49c4467aa6 /src/comp
parentReuse a single work buffer every time the SHA1 message block is processed. (diff)
downloadrust-e9c12ab1d019b42e5427e31bfa49f1f799e84165.tar.xz
rust-e9c12ab1d019b42e5427e31bfa49f1f799e84165.zip
Rewrite comp/middle/resolve.rs
* Cleans up the algorithm * Move first pass to walk (second still folds) * Support part of a type/value namespace split (crate metadata and module indices still need to be taught about this) * Remove a few blatant inefficiencies (import tables being recreated for every lookup, most importantly)
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/front/ast.rs6
-rw-r--r--src/comp/front/creader.rs10
-rw-r--r--src/comp/front/parser.rs3
-rw-r--r--src/comp/middle/fold.rs15
-rw-r--r--src/comp/middle/metadata.rs2
-rw-r--r--src/comp/middle/resolve.rs1170
-rw-r--r--src/comp/middle/trans.rs3
-rw-r--r--src/comp/pretty/pprust.rs2
8 files changed, 556 insertions, 655 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index fc2c04f4..71d187ff 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -403,7 +403,7 @@ type variant = spanned[variant_];
type view_item = spanned[view_item_];
tag view_item_ {
view_item_use(ident, vec[@meta_item], def_id, Option.t[int]);
- view_item_import(ident, vec[ident], def_id, Option.t[def]);
+ view_item_import(ident, vec[ident], def_id);
view_item_export(ident);
}
@@ -432,7 +432,7 @@ fn index_view_item(mod_index index, @view_item it) {
case(ast.view_item_use(?id, _, _, _)) {
index.insert(id, ast.mie_view_item(it));
}
- case(ast.view_item_import(?def_ident,_,_,_)) {
+ case(ast.view_item_import(?def_ident,_,_)) {
index.insert(def_ident, ast.mie_view_item(it));
}
case(ast.view_item_export(_)) {
@@ -488,7 +488,7 @@ fn index_native_item(native_mod_index index, @native_item it) {
fn index_native_view_item(native_mod_index index, @view_item it) {
alt (it.node) {
- case(ast.view_item_import(?def_ident,_,_,_)) {
+ case(ast.view_item_import(?def_ident,_,_)) {
index.insert(def_ident, ast.nmie_view_item(it));
}
case(ast.view_item_export(_)) {
diff --git a/src/comp/front/creader.rs b/src/comp/front/creader.rs
index 832ef131..dd913b53 100644
--- a/src/comp/front/creader.rs
+++ b/src/comp/front/creader.rs
@@ -635,14 +635,8 @@ fn list_crate_metadata(vec[u8] bytes, IO.writer out) {
fn describe_def(&EBML.doc items, ast.def_id id) -> str {
if (id._0 != 0) {ret "external";}
- alt (maybe_find_item(id._1 as int, items)) {
- case (Option.some[EBML.doc](?item)) {
- ret item_kind_to_str(item_kind(item));
- }
- case (Option.none[EBML.doc]) {
- ret "??"; // Native modules don't seem to get item entries.
- }
- }
+ auto item = find_item(id._1, items);
+ ret item_kind_to_str(item_kind(item));
}
fn item_kind_to_str(u8 kind) -> str {
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index 733d5050..46cad2fd 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -2309,8 +2309,7 @@ fn parse_rest_import_name(parser p, ast.ident first,
}
}
auto import_decl = ast.view_item_import(defined_id, identifiers,
- p.next_def_id(),
- none[ast.def]);
+ p.next_def_id());
ret @spanned(lo, hi, import_decl);
}
diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs
index 2f4cbafa..62521067 100644
--- a/src/comp/middle/fold.rs
+++ b/src/comp/middle/fold.rs
@@ -291,8 +291,7 @@ type ast_fold[ENV] =
(fn(&ENV e, &span sp, &ident i,
&vec[ident] idents,
- &def_id id,
- &Option.t[def]) -> @view_item) fold_view_item_import,
+ &def_id id) -> @view_item) fold_view_item_import,
(fn(&ENV e, &span sp,
&ident i) -> @view_item) fold_view_item_export,
@@ -981,10 +980,9 @@ fn fold_view_item[ENV](&ENV env, &ast_fold[ENV] fld, &@view_item vi)
ret fld.fold_view_item_use(env_, vi.span, ident, meta_items,
def_id, cnum);
}
- case (ast.view_item_import(?def_ident, ?idents, ?def_id,
- ?target_def)) {
+ case (ast.view_item_import(?def_ident, ?idents, ?def_id)) {
ret fld.fold_view_item_import(env_, vi.span, def_ident, idents,
- def_id, target_def);
+ def_id);
}
case (ast.view_item_export(?def_ident)) {
@@ -1538,10 +1536,9 @@ fn identity_fold_view_item_use[ENV](&ENV e, &span sp, &ident i,
}
fn identity_fold_view_item_import[ENV](&ENV e, &span sp, &ident i,
- &vec[ident] is, &def_id id,
- &Option.t[def] target_def)
+ &vec[ident] is, &def_id id)
-> @view_item {
- ret @respan(sp, ast.view_item_import(i, is, id, target_def));
+ ret @respan(sp, ast.view_item_import(i, is, id));
}
fn identity_fold_view_item_export[ENV](&ENV e, &span sp, &ident i)
@@ -1747,7 +1744,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
fold_view_item_use =
bind identity_fold_view_item_use[ENV](_,_,_,_,_,_),
fold_view_item_import =
- bind identity_fold_view_item_import[ENV](_,_,_,_,_,_),
+ bind identity_fold_view_item_import[ENV](_,_,_,_,_),
fold_view_item_export =
bind identity_fold_view_item_export[ENV](_,_,_),
diff --git a/src/comp/middle/metadata.rs b/src/comp/middle/metadata.rs
index dfc441a9..eedff3bf 100644
--- a/src/comp/middle/metadata.rs
+++ b/src/comp/middle/metadata.rs
@@ -513,7 +513,7 @@ fn encode_info_for_item(@trans.crate_ctxt cx, &EBML.writer ebml_w,
encode_kind(ebml_w, 'm' as u8);
EBML.end_tag(ebml_w);
}
- case (ast.item_native_mod(_, _, ?did)) {
+ case (ast.item_native_mod(?id, _, ?did)) {
EBML.start_tag(ebml_w, tag_items_data_item);
encode_def_id(ebml_w, did);
encode_kind(ebml_w, 'n' as u8);
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs
index 5fb2eb04..92248ed9 100644
--- a/src/comp/middle/resolve.rs
+++ b/src/comp/middle/resolve.rs
@@ -1,13 +1,15 @@
import front.ast;
import front.ast.ident;
import front.ast.def;
+import front.ast.def_id;
import front.ast.ann;
import front.creader;
-import driver.session;
+import driver.session.session;
import util.common.new_def_hash;
import util.common.span;
import util.typestate_ann.ts_ann;
import std.Map.hashmap;
+import std.List;
import std.List.list;
import std.List.nil;
import std.List.cons;
@@ -17,787 +19,693 @@ import std.Option.none;
import std.Str;
import std.Vec;
+// Resolving happens in two passes. The first pass collects defids of all
+// (internal) imports and modules, so that they can be looked up when needed,
+// and then uses this information to resolve the imports. The second pass
+// locates all names (in expressions, types, and alt patterns) and resolves
+// them, storing the resulting def in the AST nodes.
+
tag scope {
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);
}
-type env = rec(list[scope] scopes,
- session.session sess);
+tag wrap_mod {
+ wmod(ast._mod);
+ wnmod(ast.native_mod);
+}
+tag import_state {
+ todo(@ast.view_item, list[scope]);
+ resolving(span);
+ resolved(Option.t[def] /* value */, Option.t[def] /* type */);
+}
+
+type env = rec(std.Map.hashmap[def_id,import_state] imports,
+ std.Map.hashmap[def_id,@wrap_mod] mod_map,
+ std.Map.hashmap[def_id,vec[ident]] ext_map,
+ session sess);
+
+// Used to distinguish between lookups from outside and from inside modules,
+// since export restrictions should only be applied for the former.
+tag dir { inside; outside; }
tag namespace {
ns_value;
ns_type;
}
-// This indicates whether we're searching up the scope chain or whether we've
-// found a path component and started following it back down, which has an
-// effect on export visibility
-tag direction {
- up;
- down;
-}
-
-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 {
- def_wrap_use(@ast.view_item);
- 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;
+fn resolve_crate(session sess, @ast.crate crate) -> @ast.crate {
+ auto e = @rec(imports = new_def_hash[import_state](),
+ mod_map = new_def_hash[@wrap_mod](),
+ ext_map = new_def_hash[vec[ident]](),
+ sess = sess);
+ map_crate(e, *crate);
+ resolve_imports(*e);
+ ret resolve_names(e, *crate);
}
-fn unwrap_def(def_wrap d) -> def {
- alt (d) {
- case (def_wrap_use(?it)) {
- alt (it.node) {
- case (ast.view_item_use(_, _, ?id, _)) {
- ret ast.def_use(id);
- }
- }
- }
- case (def_wrap_import(?it)) {
- alt (it.node) {
- case (ast.view_item_import(_, _, ?id, ?target_def)) {
- alt (target_def) {
- case (some[def](?d)) {
- ret d;
- }
- case (none[def]) {
- fail;
- }
- }
- }
+// Locate all modules and imports and index them, so that the next passes can
+// resolve through them.
+
+fn map_crate(&@env e, &ast.crate c) {
+ auto cell = @mutable nil[scope];
+ auto v = rec(visit_crate_pre = bind push_env_for_crate(cell, _),
+ visit_crate_post = bind pop_env_for_crate(cell, _),
+ visit_view_item_pre = bind visit_view_item(e, cell, _),
+ visit_item_pre = bind push_env_for_item_map_mod(e, cell, _),
+ visit_item_post = bind pop_env_for_item(cell, _)
+ with walk.default_visitor());
+ walk.walk_crate(v, c);
+
+ // Helpers for this pass.
+ fn push_env_for_crate(@mutable list[scope] sc, &ast.crate c) {
+ *sc = cons[scope](scope_crate(@c), @*sc);
+ }
+ fn pop_env_for_crate(@mutable list[scope] sc, &ast.crate c) {
+ *sc = List.cdr(*sc);
+ }
+ fn push_env_for_item_map_mod(@env e, @mutable list[scope] sc,
+ &@ast.item i) {
+ *sc = cons[scope](scope_item(i), @*sc);
+ alt (i.node) {
+ case (ast.item_mod(_, ?md, ?defid)) {
+ e.mod_map.insert(defid, @wmod(md));
}
- }
- case (def_wrap_mod(?m)) {
- alt (m.node) {
- case (ast.item_mod(_, _, ?id)) {
- ret ast.def_mod(id);
- }
+ case (ast.item_native_mod(_, ?nmd, ?defid)) {
+ e.mod_map.insert(defid, @wnmod(nmd));
}
+ case (_) {}
}
- case (def_wrap_native_mod(?m)) {
- alt (m.node) {
- case (ast.item_native_mod(_, _, ?id)) {
- ret ast.def_native_mod(id);
- }
+ }
+ fn pop_env_for_item(@mutable list[scope] sc, &@ast.item i) {
+ *sc = List.cdr(*sc);
+ }
+ fn visit_view_item(@env e, @mutable list[scope] sc, &@ast.view_item i) {
+ alt (i.node) {
+ case (ast.view_item_import(_, ?ids, ?defid)) {
+ e.imports.insert(defid, todo(i, *sc));
}
- }
- 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;
- }
- case (def_wrap_expr_field(_, ?d)) {
- ret d;
+ case (_) {}
}
}
}
-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);
- }
+fn resolve_imports(&env e) {
+ for each (@tup(def_id, import_state) it in e.imports.items()) {
+ alt (it._1) {
+ case (todo(?item, ?sc)) {
+ resolve_import(e, item, sc);
}
- ret some[def_wrap](dw);
+ case (resolved(_, _)) {}
}
}
}
-// Follow the path of an import and return what it ultimately points to.
-
-// If used after imports are resolved, import_id is none.
-
-fn find_final_def(&env e, import_map index,
- &span sp, vec[ident] idents, namespace ns,
- Option.t[ast.def_id] import_id) -> def_wrap {
-
- // We are given a series of identifiers (p.q.r) and we know that
- // in the environment 'e' the identifier 'p' was resolved to 'd'. We
- // should return what p.q.r points to in the end.
- fn found_something(&env e, import_map index,
- &span sp, vec[ident] idents, namespace ns,
- def_wrap d) -> def_wrap {
-
- fn found_mod(&env e, &import_map index, &span sp,
- vec[ident] idents, namespace ns,
- @ast.item i) -> 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_item(empty_e, i);
- auto next_i = rest_idents.(0);
- auto next_ = lookup_name_wrapped(tmp_e, next_i, ns, down);
- 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_item(e, i);
- ret found_something(combined_e, index, sp,
- rest_idents, ns, next._1);
- }
- }
- }
-
- // TODO: Refactor with above.
- fn found_external_mod(&env e, &import_map index, &span sp,
- vec[ident] idents, namespace ns,
- 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, ns, down);
- 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, ns, 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);
- 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) {
- case (def_wrap_import(?imp)) {
- alt (imp.node) {
- case (ast.view_item_import(_, ?new_idents, ?d, _)) {
- auto x = find_final_def(e, index, sp, new_idents, ns,
- some(d));
- ret found_something(e, index, sp, idents, ns, x);
- }
- }
- }
- case (_) {
- }
- }
- auto len = Vec.len[ident](idents);
- if (len == 1u) {
- ret d;
- }
- alt (d) {
- case (def_wrap_mod(?i)) {
- ret found_mod(e, index, sp, idents, ns, i);
- }
- case (def_wrap_native_mod(?i)) {
- ret found_mod(e, index, sp, idents, ns, i);
- }
- case (def_wrap_external_mod(?mod_id)) {
- ret found_external_mod(e, index, sp, idents, ns, mod_id);
- }
- case (def_wrap_external_native_mod(?mod_id)) {
- ret found_external_mod(e, index, sp, idents, ns, mod_id);
- }
- case (def_wrap_use(?vi)) {
- alt (vi.node) {
- case (ast.view_item_use(_, _, _, ?cnum_opt)) {
- auto cnum = Option.get[int](cnum_opt);
- ret found_crate(e, index, sp, idents, cnum);
- }
- }
+fn resolve_names(&@env e, &ast.crate c) -> @ast.crate {
+ auto fld = @rec(fold_pat_tag = bind fold_pat_tag(e,_,_,_,_,_,_),
+ fold_expr_path = bind fold_expr_path(e,_,_,_,_,_),
+ fold_ty_path = bind fold_ty_path(e,_,_,_,_),
+ update_env_for_crate = bind update_env_for_crate(_,_),
+ update_env_for_item = bind update_env_for_item(_,_),
+ update_env_for_native_item =
+ bind update_env_for_native_item(_,_),
+ update_env_for_block = bind update_env_for_block(_,_),
+ update_env_for_arm = bind update_env_for_arm(_,_),
+ update_env_for_expr = bind update_env_for_expr(_,_)
+ with *fold.new_identity_fold[list[scope]]());
+ ret fold.fold_crate(nil[scope], fld, @c);
+
+ // Helpers for this pass
+
+ fn update_env_for_crate(&list[scope] sc, &@ast.crate c) -> list[scope] {
+ ret cons[scope](scope_crate(c), @sc);
+ }
+ fn update_env_for_item(&list[scope] sc, &@ast.item i) -> list[scope] {
+ ret cons[scope](scope_item(i), @sc);
+ }
+ fn update_env_for_native_item(&list[scope] sc, &@ast.native_item i)
+ -> list[scope] {
+ ret cons[scope](scope_native_item(i), @sc);
+ }
+ fn update_env_for_block(&list[scope] sc, &ast.block b) -> list[scope] {
+ ret cons[scope](scope_block(b), @sc);
+ }
+ fn update_env_for_expr(&list[scope] sc, &@ast.expr x) -> list[scope] {
+ alt (x.node) {
+ case (ast.expr_for(?d, _, _, _)) {
+ ret cons[scope](scope_loop(d), @sc);
}
- case (def_wrap_other(?d)) {
- let uint l = Vec.len[ident](idents);
- ret def_wrap_expr_field(l, d);
+ case (ast.expr_for_each(?d, _, _, _)) {
+ ret cons[scope](scope_loop(d), @sc);
}
+ case (_) { ret sc; }
}
- fail;
}
+ fn update_env_for_arm(&list[scope] sc, &ast.arm p) -> list[scope] {
+ ret cons[scope](scope_arm(p), @sc);
+ }
+}
- if (import_id != none[ast.def_id]) {
- alt (index.find(Option.get[ast.def_id](import_id))) {
- case (some[def_wrap](?x)) {
- alt (x) {
- case (def_wrap_resolving) {
- e.sess.span_err(sp, "cyclic import");
- fail;
- }
- case (_) {
- ret x;
- }
- }
- }
- case (none[def_wrap]) {
- }
+fn lookup_import(&env e, def_id defid, namespace ns) -> Option.t[def] {
+ alt (e.imports.get(defid)) {
+ case (todo(?item, ?sc)) {
+ resolve_import(e, item, sc);
+ ret lookup_import(e, defid, ns);
}
- index.insert(Option.get[ast.def_id](import_id), def_wrap_resolving);
- }
- auto first = idents.(0);
- auto d_ = lookup_name_wrapped(e, first, ns, up);
- alt (d_) {
- case (none[tup(@env, def_wrap)]) {
- e.sess.span_err(sp, "unresolved name: " + first);
- fail;
+ case (resolving(?sp)) {
+ e.sess.span_err(sp, "cyclic import");
}
- case (some[tup(@env, def_wrap)](?d)) {
- auto x = found_something(*d._0, index, sp, idents, ns, d._1);
- if (import_id != none[ast.def_id]) {
- index.insert(Option.get[ast.def_id](import_id), x);
- }
- ret x;
+ case (resolved(?val, ?typ)) {
+ ret alt (ns) { case (ns_value) { val }
+ case (ns_type) { typ } };
}
}
}
-fn lookup_name_wrapped(&env e, ast.ident i, namespace ns, direction dir)
- -> Option.t[tup(@env, def_wrap)] {
-
- // log "resolving name " + i;
-
- fn found_def_item(@ast.item i, namespace ns) -> def_wrap {
- alt (i.node) {
- case (ast.item_const(_, _, _, ?id, _)) {
- ret def_wrap_other(ast.def_const(id));
- }
- case (ast.item_fn(_, _, _, ?id, _)) {
- ret def_wrap_other(ast.def_fn(id));
- }
- case (ast.item_mod(_, _, ?id)) {
- ret def_wrap_mod(i);
- }
- case (ast.item_native_mod(_, _, ?id)) {
- ret def_wrap_native_mod(i);
- }
- case (ast.item_ty(_, _, _, ?id, _)) {
- ret def_wrap_other(ast.def_ty(id));
- }
- case (ast.item_tag(_, _, _, ?id, _)) {
- ret def_wrap_other(ast.def_ty(id));
- }
- case (ast.item_obj(_, _, _, ?odid, _)) {
- alt (ns) {
- case (ns_value) {
- ret def_wrap_other(ast.def_obj(odid.ctor));
- }
- case (ns_type) {
- ret def_wrap_other(ast.def_obj(odid.ty));
- }
- }
- }
+fn resolve_import(&env e, &@ast.view_item it, &list[scope] sc) {
+ auto defid; auto ids;
+ alt (it.node) {
+ case (ast.view_item_import(_, ?_ids, ?_defid)) {
+ defid = _defid; ids = _ids;
}
}
-
- fn found_def_native_item(@ast.native_item i) -> def_wrap {
- alt (i.node) {
- case (ast.native_item_ty(_, ?id)) {
- ret def_wrap_other(ast.def_native_ty(id));
- }
- case (ast.native_item_fn(_, _, _, _, ?id, _)) {
- ret def_wrap_other(ast.def_native_fn(id));
+ e.imports.insert(defid, resolving(it.span));
+
+ auto n_idents = Vec.len(ids);
+ auto end_id = ids.(n_idents - 1u);
+
+ if (n_idents == 1u) {
+ register(e, defid, it.span, end_id,
+ lookup_in_scope(e, sc, end_id, ns_value),
+ lookup_in_scope(e, sc, end_id, ns_type));
+ } else {
+ auto dcur = lookup_in_scope_strict(e, sc, it.span, ids.(0), ns_value);
+ auto i = 1u;
+ while (true) {
+ if (!is_module(dcur)) {
+ e.sess.span_err(it.span, ids.(i-1u) +
+ " is not a module or crate");
+ }
+ if (i == n_idents - 1u) {
+ register(e, defid, it.span, end_id,
+ lookup_in_mod(e, dcur, end_id, ns_value, outside),
+ lookup_in_mod(e, dcur, end_id, ns_type, outside));
+ break;
+ } else {
+ dcur = lookup_in_mod_strict(e, dcur, it.span, ids.(i),
+ ns_value, outside);
+ i += 1u;
}
}
}
- fn found_def_view(@ast.view_item i) -> def_wrap {
- alt (i.node) {
- case (ast.view_item_use(_, _, ?id, _)) {
- ret def_wrap_use(i);
- }
- case (ast.view_item_import(_, ?idents,?d, _)) {
- ret def_wrap_import(i);
- }
+ fn register(&env e, def_id defid, &span sp, ident id,
+ Option.t[def] val, Option.t[def] typ) {
+ if (val == none[def] && typ == none[def]) {
+ unresolved(e, sp, id, "import");
}
- fail;
+ e.imports.insert(defid, resolved(val, typ));
}
+}
- fn check_mod(ast.ident i, ast._mod m, namespace ns,
- direction dir) -> Option.t[def_wrap] {
-
- fn visible(ast.ident i, ast._mod m, direction dir) -> bool {
+// We received a path expression of the following form:
+//
+// a.b.c.d
+//
+// Somewhere along this path there might be a split from a path-expr
+// to a runtime field-expr. For example:
+//
+// 'a' could be the name of a variable in the local scope
+// and 'b.c.d' could be a field-sequence inside it.
+//
+// Or:
+//
+// 'a.b' could be a module path to a constant record, and 'c.d'
+// could be a field within it.
+//
+// Our job here is to figure out what the prefix of 'a.b.c.d' is that
+// corresponds to a static binding-name (a module or slot, with no type info)
+// and split that off as the 'primary' expr_path, with secondary expr_field
+// expressions tacked on the end.
- alt (dir) {
- case (up) {
- ret true;
- }
- case (down) {
- // fall through
- }
- }
+fn fold_expr_path(@env e, &list[scope] sc, &span sp, &ast.path p,
+ &Option.t[def] d, &ann a) -> @ast.expr {
+ auto idents = p.node.idents;
+ auto n_idents = Vec.len(idents);
+ assert (n_idents != 0u);
- ret ast.is_exported(i, m);
- }
+ auto dcur = lookup_in_scope_strict(*e, sc, sp, idents.(0), ns_value);
+ auto i = 1u;
+ while (i < n_idents) {
+ if (!is_module(dcur)) { break; }
+ dcur = lookup_in_mod_strict(*e, dcur, sp, idents.(i), ns_value,
+ outside);
+ i += 1u;
+ }
+ if (is_module(dcur)) {
+ e.sess.span_err(sp, "can't refer to a module as a first-class value");
+ }
- alt (m.index.find(i)) {
- case (some[ast.mod_index_entry](?ent)) {
- alt (ent) {
- case (ast.mie_view_item(?view_item)) {
- ret some(found_def_view(view_item));
- }
- case (ast.mie_item(?item)) {
- if (visible(i, m, dir)) {
- ret some(found_def_item(item, ns));
- } else {
- ret none[def_wrap];
- }
- }
- case (ast.mie_tag_variant(?item, ?variant_idx)) {
- alt (item.node) {
- case (ast.item_tag(_, ?variants, _, ?tid, _)) {
- if (visible(i, m, dir)) {
- auto vid = variants.(variant_idx).node.id;
- auto t = ast.def_variant(tid, vid);
- ret some[def_wrap](def_wrap_other(t));
- } else {
- ret none[def_wrap];
- }
- }
- case (_) {
- log_err "tag item not actually a tag";
- fail;
- }
- }
- }
- }
- }
- case (none[ast.mod_index_entry]) {
- ret none[def_wrap];
- }
- }
+ p = rec(node=rec(idents=Vec.slice(idents, 0u, i) with p.node) with p);
+ auto ex = @fold.respan(sp, ast.expr_path(p, some(dcur), a));
+ while (i < n_idents) {
+ ex = @fold.respan(sp, ast.expr_field(ex, idents.(i), a));
+ i += 1u;
}
+ ret ex;
+}
- fn check_native_mod(ast.ident i, ast.native_mod m) -> Option.t[def_wrap] {
- alt (m.index.find(i)) {
- case (some[ast.native_mod_index_entry](?ent)) {
- alt (ent) {
- case (ast.nmie_view_item(?view_item)) {
- ret some(found_def_view(view_item));
- }
- case (ast.nmie_item(?item)) {
- ret some(found_def_native_item(item));
- }
- }
- }
- case (none[ast.native_mod_index_entry]) {
- ret none[def_wrap];
- }
+fn lookup_path_strict(&env e, &list[scope] sc, &span sp, vec[ident] idents,
+ namespace ns) -> def {
+ auto n_idents = Vec.len(idents);
+ auto dcur = lookup_in_scope_strict(e, sc, sp, idents.(0), ns);
+ auto i = 1u;
+ while (i < n_idents) {
+ if (!is_module(dcur)) {
+ e.sess.span_err(sp, idents.(i-1u) +
+ " can't be dereferenced as a module");
}
+ dcur = lookup_in_mod_strict(e, dcur, sp, idents.(i), ns, outside);
+ i += 1u;
}
-
- fn handle_fn_decl(ast.ident identifier, &ast.fn_decl decl,
- &vec[ast.ty_param] ty_params) -> Option.t[def_wrap] {
- for (ast.arg a in decl.inputs) {
- if (Str.eq(a.ident, identifier)) {
- auto t = ast.def_arg(a.id);
- ret some(def_wrap_other(t));
- }
+ if (is_module(dcur)) {
+ e.sess.span_err(sp, Str.connect(idents, ".") +
+ " is a module, not a " + ns_name(ns));
+ }
+ ret dcur;
+}
+
+fn fold_pat_tag(@env e, &list[scope] sc, &span sp, &ast.path p,
+ &vec[@ast.pat] args, &Option.t[ast.variant_def] old_def,
+ &ann a) -> @ast.pat {
+ alt (lookup_path_strict(*e, sc, sp, p.node.idents, ns_value)) {
+ case (ast.def_variant(?did, ?vid)) {
+ auto new_def = some[ast.variant_def](tup(did, vid));
+ ret @fold.respan[ast.pat_](sp, ast.pat_tag(p, args, new_def, a));
}
-
- auto i = 0u;
- for (ast.ty_param tp in ty_params) {
- if (Str.eq(tp, identifier)) {
- auto t = ast.def_ty_arg(i);
- ret some(def_wrap_other(t));
- }
- i += 1u;
+ case (_) {
+ e.sess.span_err(sp, "not a tag variant: " +
+ Str.connect(p.node.idents, "."));
+ fail;
}
- ret none[def_wrap];
}
+}
- fn found_tag(@ast.item item, uint variant_idx) -> def_wrap {
- alt (item.node) {
- case (ast.item_tag(_, ?variants, _, ?tid, _)) {
- auto vid = variants.(variant_idx).node.id;
- auto t = ast.def_variant(tid, vid);
- ret def_wrap_other(t);
- }
- case (_) {
- log_err "tag item not actually a tag";
- fail;
- }
- }
+fn fold_ty_path(@env e, &list[scope] sc, &span sp, &ast.path p,
+ &Option.t[def] d) -> @ast.ty {
+ auto new_def = lookup_path_strict(*e, sc, sp, p.node.idents, ns_type);
+ ret @fold.respan[ast.ty_](sp, ast.ty_path(p, some(new_def)));
+}
+
+fn is_module(def d) -> bool {
+ alt (d) {
+ case (ast.def_mod(_)) { ret true; }
+ case (ast.def_native_mod(_)) { ret true; }
+ case (_) { ret false; }
}
+}
- fn check_block(ast.ident i, &ast.block_ b, namespace ns)
- -> Option.t[def_wrap] {
- alt (b.index.find(i)) {
- case (some[ast.block_index_entry](?ix)) {
- alt(ix) {
- case (ast.bie_item(?it)) {
- ret some(found_def_item(it, ns));
- }
- case (ast.bie_local(?l)) {
- auto t = ast.def_local(l.id);
- ret some(def_wrap_other(t));
- }
- case (ast.bie_tag_variant(?item, ?variant_idx)) {
- ret some(found_tag(item, variant_idx));
- }
- }
- }
- case (_) { ret none[def_wrap]; }
+fn ns_name(namespace ns) -> str {
+ alt (ns) {
+ case (ns_type) { ret "typename"; }
+ case (ns_value) { ret "name"; }
+ }
+}
+
+fn unresolved(&env e, &span sp, ident id, str kind) {
+ e.sess.span_err(sp, "unresolved " + kind + ": " + id);
+}
+
+fn lookup_in_scope_strict(&env e, list[scope] sc, &span sp, ident id,
+ namespace ns) -> def {
+ alt (lookup_in_scope(e, sc, id, ns)) {
+ case (none[def]) {
+ unresolved(e, sp, id, ns_name(ns));
+ fail;
+ }
+ case (some[def](?d)) {
+ ret d;
}
}
+}
- fn in_scope(&session.session sess, ast.ident identifier, &scope s,
- namespace ns, direction dir) -> Option.t[def_wrap] {
+fn lookup_in_scope(&env e, list[scope] sc, ident id, namespace ns)
+ -> Option.t[def] {
+ fn in_scope(&env e, ident id, &scope s, namespace ns)
+ -> Option.t[def] {
alt (s) {
-
case (scope_crate(?c)) {
- ret check_mod(identifier, c.node.module, ns, dir);
+ ret lookup_in_regular_mod(e, c.node.module, id, ns, inside);
}
-
case (scope_item(?it)) {
alt (it.node) {
case (ast.item_fn(_, ?f, ?ty_params, _, _)) {
- ret handle_fn_decl(identifier, f.decl, ty_params);
+ ret lookup_in_fn(id, f.decl, ty_params, ns);
}
case (ast.item_obj(_, ?ob, ?ty_params, _, _)) {
- for (ast.obj_field f in ob.fields) {
- if (Str.eq(f.ident, identifier)) {
- auto t = ast.def_obj_field(f.id);
- ret some(def_wrap_other(t));
- }
- }
-
- auto i = 0u;
- for (ast.ty_param tp in ty_params) {
- if (Str.eq(tp, identifier)) {
- auto t = ast.def_ty_arg(i);
- ret some(def_wrap_other(t));
- }
- i += 1u;
- }
+ ret lookup_in_obj(id, ob, ty_params, ns);
}
- case (ast.item_tag(_,?variants,?ty_params,?tag_id,_)) {
- auto i = 0u;
- for (ast.ty_param tp in ty_params) {
- if (Str.eq(tp, identifier)) {
- auto t = ast.def_ty_arg(i);
- ret some(def_wrap_other(t));
- }
- i += 1u;
+ case (ast.item_tag(_, _, ?ty_params, _, _)) {
+ if (ns == ns_type) {
+ ret lookup_in_ty_params(id, ty_params);
}
}
case (ast.item_mod(_, ?m, _)) {
- ret check_mod(identifier, m, ns, dir);
+ ret lookup_in_regular_mod(e, m, id, ns, inside);
}
case (ast.item_native_mod(_, ?m, _)) {
- ret check_native_mod(identifier, m);
+ ret lookup_in_native_mod(e, m, id, ns);
}
case (ast.item_ty(_, _, ?ty_params, _, _)) {
- auto i = 0u;
- for (ast.ty_param tp in ty_params) {
- if (Str.eq(tp, identifier)) {
- auto t = ast.def_ty_arg(i);
- ret some(def_wrap_other(t));
- }
- i += 1u;
+ if (ns == ns_type) {
+ ret lookup_in_ty_params(id, ty_params);
}
}
- case (_) { /* fall through */ }
+ case (_) {}
}
}
case (scope_native_item(?it)) {
alt (it.node) {
case (ast.native_item_fn(_, _, ?decl, ?ty_params, _, _)) {
- ret handle_fn_decl(identifier, decl, ty_params);
+ ret lookup_in_fn(id, decl, ty_params, ns);
}
}
}
- 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)) {
- if (Str.eq(local.ident, identifier)) {
- auto lc = ast.def_local(local.id);
- ret some(def_wrap_other(lc));
+ if (ns == ns_value) {
+ alt (d.node) {
+ case (ast.decl_local(?local)) {
+ if (Str.eq(local.ident, id)) {
+ ret some(ast.def_local(local.id));
+ }
}
}
}
}
case (scope_block(?b)) {
- ret check_block(identifier, b.node, ns);
+ ret lookup_in_block(id, b.node, ns);
}
case (scope_arm(?a)) {
- alt (a.index.find(identifier)) {
- case (some[ast.def_id](?did)) {
- auto t = ast.def_binding(did);
- ret some[def_wrap](def_wrap_other(t));
+ if (ns == ns_value) {
+ alt (a.index.find(id)) {
+ case (some[def_id](?did)) {
+ ret some(ast.def_binding(did));
+ }
+ case (_) {}
}
- case (_) { /* fall through */ }
}
}
}
- ret none[def_wrap];
+ ret none[def];
}
- alt (e.scopes) {
- case (nil[scope]) {
- ret none[tup(@env, def_wrap)];
- }
- case (cons[scope](?hd, ?tl)) {
- auto x = in_scope(e.sess, i, hd, ns, dir);
- alt (x) {
- case (some[def_wrap](?x)) {
- ret some(tup(@e, x));
- }
- case (none[def_wrap]) {
- auto outer_env = rec(scopes = *tl with e);
- ret lookup_name_wrapped(outer_env, i, ns, up);
+ while (true) {
+ alt (sc) {
+ case (nil[scope]) {
+ ret none[def];
+ }
+ case (cons[scope](?hd, ?tl)) {
+ alt (in_scope(e, id, hd, ns)) {
+ case (some[def](?x)) { ret some(x); }
+ case (_) { sc = *tl; }
}
}
}
}
}
-fn fold_pat_tag(&env e, &span sp, &ast.path p, &vec[@ast.pat] args,
- &Option.t[ast.variant_def] old_def,
- &ann a) -> @ast.pat {
- auto len = Vec.len[ast.ident](p.node.idents);
- auto last_id = p.node.idents.(len - 1u);
- auto new_def;
- auto index = new_def_hash[def_wrap]();
- auto d = find_final_def(e, index, sp, p.node.idents, ns_value,
- none[ast.def_id]);
- alt (unwrap_def(d)) {
- case (ast.def_variant(?did, ?vid)) {
- new_def = some[ast.variant_def](tup(did, vid));
- }
- case (_) {
- e.sess.span_err(sp, "not a tag variant: " + last_id);
- new_def = none[ast.variant_def];
+fn lookup_in_ty_params(ident id, &vec[ast.ty_param] ty_params)
+ -> Option.t[def] {
+ auto i = 0u;
+ for (ast.ty_param tp in ty_params) {
+ if (Str.eq(tp, id)) {
+ ret some(ast.def_ty_arg(i));
}
+ i += 1u;
}
+ ret none[def];
+}
- ret @fold.respan[ast.pat_](sp, ast.pat_tag(p, args, new_def, a));
+fn lookup_in_fn(ident id, &ast.fn_decl decl,
+ &vec[ast.ty_param] ty_params, namespace ns) -> Option.t[def] {
+ if (ns == ns_value) {
+ for (ast.arg a in decl.inputs) {
+ if (Str.eq(a.ident, id)) {
+ ret some(ast.def_arg(a.id));
+ }
+ }
+ ret none[def];
+ } else {
+ ret lookup_in_ty_params(id, ty_params);
+ }
}
-// We received a path expression of the following form:
-//
-// a.b.c.d
-//
-// Somewhere along this path there might be a split from a path-expr
-// to a runtime field-expr. For example:
-//
-// 'a' could be the name of a variable in the local scope
-// and 'b.c.d' could be a field-sequence inside it.
-//
-// Or:
-//
-// 'a.b' could be a module path to a constant record, and 'c.d'
-// could be a field within it.
-//
-// Our job here is to figure out what the prefix of 'a.b.c.d' is that
-// corresponds to a static binding-name (a module or slot, with no type info)
-// and split that off as the 'primary' expr_path, with secondary expr_field
-// expressions tacked on the end.
+fn lookup_in_obj(ident id, &ast._obj ob, &vec[ast.ty_param] ty_params,
+ namespace ns) -> Option.t[def] {
+ if (ns == ns_value) {
+ for (ast.obj_field f in ob.fields) {
+ if (Str.eq(f.ident, id)) {
+ ret some(ast.def_obj_field(f.id));
+ }
+ }
+ ret none[def];
+ } else {
+ ret lookup_in_ty_params(id, ty_params);
+ }
+}
-fn fold_expr_path(&env e, &span sp, &ast.path p, &Option.t[def] d,
- &ann a) -> @ast.expr {
- auto n_idents = Vec.len[ast.ident](p.node.idents);
- assert (n_idents != 0u);
+fn lookup_in_block(ident id, &ast.block_ b, namespace ns)
+ -> Option.t[def] {
+ alt (b.index.find(id)) {
+ case (some[ast.block_index_entry](?ix)) {
+ alt (ix) {
+ case (ast.bie_item(?it)) {
+ ret found_def_item(it, ns);
+ }
+ case (ast.bie_local(?l)) {
+ if (ns == ns_value) {
+ ret some(ast.def_local(l.id));
+ }
+ }
+ case (ast.bie_tag_variant(?item, ?variant_idx)) {
+ if (ns == ns_value) {
+ ret some(found_def_tag(item, variant_idx));
+ }
+ }
+ }
+ }
+ case (_) { }
+ }
+ ret none[def];
+}
- auto index = new_def_hash[def_wrap]();
- auto d = find_final_def(e, index, sp, p.node.idents, ns_value,
- none[ast.def_id]);
- let uint path_len = 0u;
- alt (d) {
- case (def_wrap_expr_field(?remaining, _)) {
- path_len = n_idents - remaining + 1u;
+fn found_def_item(@ast.item i, namespace ns) -> Option.t[def] {
+ alt (i.node) {
+ case (ast.item_const(_, _, _, ?id, _)) {
+ if (ns == ns_value) {
+ ret some(ast.def_const(id));
+ }
}
- case (def_wrap_other(_)) {
- path_len = n_idents;
+ case (ast.item_fn(_, _, _, ?id, _)) {
+ if (ns == ns_value) {
+ ret some(ast.def_fn(id));
+ }
}
- case (def_wrap_mod(?m)) {
- e.sess.span_err(sp,
- "can't refer to a module as a first-class value");
- fail;
+ case (ast.item_mod(_, _, ?id)) {
+ ret some(ast.def_mod(id));
}
+ case (ast.item_native_mod(_, _, ?id)) {
+ ret some(ast.def_native_mod(id));
+ }
+ case (ast.item_ty(_, _, _, ?id, _)) {
+ if (ns == ns_type) {
+ ret some(ast.def_ty(id));
+ }
+ }
+ case (ast.item_tag(_, _, _, ?id, _)) {
+ if (ns == ns_type) {
+ ret some(ast.def_ty(id));
+ }
+ }
+ case (ast.item_obj(_, _, _, ?odid, _)) {
+ if (ns == ns_value) {
+ ret some(ast.def_obj(odid.ctor));
+ } else {
+ ret some(ast.def_obj(odid.ty));
+ }
+ }
+ case (_) { }
}
- auto path_elems =
- Vec.slice[ident](p.node.idents, 0u, path_len);
- auto p_ = rec(node=rec(idents = path_elems with p.node) with p);
- auto d_ = some(unwrap_def(d));
- auto ex = @fold.respan[ast.expr_](sp, ast.expr_path(p_, d_, a));
- auto i = path_len;
- while (i < n_idents) {
- auto id = p.node.idents.(i);
- ex = @fold.respan[ast.expr_](sp, ast.expr_field(ex, id, a));
- i += 1u;
- }
- ret ex;
+ ret none[def];
}
-fn fold_view_item_import(&env e, &span sp,
- &import_map index, &ident i,
- &vec[ident] is, &ast.def_id id,
- &Option.t[def] target_id) -> @ast.view_item {
- // Produce errors for invalid imports
- auto len = Vec.len[ast.ident](is);
- auto last_id = is.(len - 1u);
- auto d = find_final_def(e, index, sp, is, ns_value, some(id));
- alt (d) {
- case (def_wrap_expr_field(?remain, _)) {
- auto ident = is.(len - remain);
- e.sess.span_err(sp, ident + " is not a module or crate");
+fn found_def_tag(@ast.item item, uint variant_idx) -> def {
+ alt (item.node) {
+ case (ast.item_tag(_, ?variants, _, ?tid, _)) {
+ auto vid = variants.(variant_idx).node.id;
+ ret ast.def_variant(tid, vid);
}
case (_) {
+ log_err "tag item not actually a tag";
+ fail;
}
}
- let Option.t[def] target_def = some(unwrap_def(d));
- ret @fold.respan[ast.view_item_](sp, ast.view_item_import(i, is, id,
- target_def));
-}
-
-fn fold_ty_path(&env e, &span sp, &ast.path p, &Option.t[def] d) -> @ast.ty {
- auto index = new_def_hash[def_wrap]();
- auto d = find_final_def(e, index, sp, p.node.idents, ns_type,
- none[ast.def_id]);
-
- ret @fold.respan[ast.ty_](sp, ast.ty_path(p, some(unwrap_def(d))));
-}
-
-fn update_env_for_crate(&env e, &@ast.crate c) -> env {
- ret rec(scopes = cons[scope](scope_crate(c), @e.scopes) with e);
-}
-
-fn update_env_for_item(&env e, &@ast.item i) -> env {
- ret rec(scopes = cons[scope](scope_item(i), @e.scopes) with e);
-}
-
-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 lookup_in_mod_strict(&env e, def m, &span sp, ident id,
+ namespace ns, dir dr) -> def {
+ alt (lookup_in_mod(e, m, id, ns, dr)) {
+ case (none[def]) {
+ unresolved(e, sp, id, ns_name(ns));
+ fail;
+ }
+ case (some[def](?d)) {
+ ret d;
+ }
+ }
}
-fn update_env_for_block(&env e, &ast.block b) -> env {
- ret rec(scopes = cons[scope](scope_block(b), @e.scopes) with e);
+fn lookup_in_mod(&env e, def m, ident id, namespace ns, dir dr)
+ -> Option.t[def] {
+ auto defid = ast.def_id_of_def(m);
+ // FIXME this causes way more metadata lookups than needed. Cache?
+ if (defid._0 != 0) { // Not in this crate (FIXME use a const, not 0)
+ auto path = vec(id);
+ // def_num=-1 is a kludge to overload def_mod for external crates,
+ // since those don't get a def num
+ if (defid._1 != -1) {
+ path = e.ext_map.get(defid) + path;
+ }
+ ret lookup_external(e, defid._0, path, ns);
+ }
+ alt (m) {
+ case (ast.def_mod(?defid)) {
+ alt (*e.mod_map.get(defid)) {
+ case (wmod(?m)) {
+ ret lookup_in_regular_mod(e, m, id, ns, dr);
+ }
+ }
+ }
+ case (ast.def_native_mod(?defid)) {
+ alt (*e.mod_map.get(defid)) {
+ case (wnmod(?m)) {
+ ret lookup_in_native_mod(e, m, id, ns);
+ }
+ }
+ }
+ }
}
-fn update_env_for_expr(&env e, &@ast.expr x) -> env {
- alt (x.node) {
- case (ast.expr_for(?d, _, _, _)) {
- ret rec(scopes = cons[scope](scope_loop(d), @e.scopes) with e);
+fn found_view_item(&env e, @ast.view_item vi, namespace ns) -> Option.t[def] {
+ alt (vi.node) {
+ case (ast.view_item_use(_, _, _, ?cnum)) {
+ ret some(ast.def_mod(tup(Option.get(cnum), -1)));
}
- case (ast.expr_for_each(?d, _, _, _)) {
- ret rec(scopes = cons[scope](scope_loop(d), @e.scopes) with e);
+ case (ast.view_item_import(_, _, ?defid)) {
+ ret lookup_import(e, defid, ns);
}
- case (_) { }
}
- ret e;
}
-fn update_env_for_arm(&env e, &ast.arm p) -> env {
- ret rec(scopes = cons[scope](scope_arm(p), @e.scopes) with e);
+fn lookup_in_regular_mod(&env e, &ast._mod md, ident id, namespace ns, dir dr)
+ -> Option.t[def] {
+ auto found = md.index.find(id);
+ if (found == none[ast.mod_index_entry] ||
+ (dr == outside && !ast.is_exported(id, md))) {
+ ret none[def];
+ }
+ alt (Option.get(found)) {
+ case (ast.mie_view_item(?view_item)) {
+ ret found_view_item(e, view_item, ns);
+ }
+ case (ast.mie_item(?item)) {
+ ret found_def_item(item, ns);
+ }
+ case (ast.mie_tag_variant(?item, ?variant_idx)) {
+ alt (item.node) {
+ case (ast.item_tag(_, ?variants, _, ?tid, _)) {
+ if (ns == ns_value) {
+ auto vid = variants.(variant_idx).node.id;
+ ret some(ast.def_variant(tid, vid));
+ } else {
+ ret none[def];
+ }
+ }
+ }
+ }
+ }
}
-fn resolve_imports(session.session sess, &@ast.crate crate) -> @ast.crate {
- let fold.ast_fold[env] fld = fold.new_identity_fold[env]();
-
- auto import_index = new_def_hash[def_wrap]();
- fld = @rec( fold_view_item_import
- = bind fold_view_item_import(_,_,import_index,_,_,_,_),
- update_env_for_crate = bind update_env_for_crate(_,_),
- update_env_for_item = bind update_env_for_item(_,_),
- update_env_for_native_item =
- bind update_env_for_native_item(_,_),
- update_env_for_block = bind update_env_for_block(_,_),
- update_env_for_arm = bind update_env_for_arm(_,_),
- update_env_for_expr = bind update_env_for_expr(_,_)
- with *fld );
-
- auto e = rec(scopes = nil[scope],
- sess = sess);
-
- ret fold.fold_crate[env](e, fld, crate);
+fn lookup_in_native_mod(&env e, &ast.native_mod md, ident id, namespace ns)
+ -> Option.t[def] {
+ auto found = md.index.find(id);
+ if (found == none[ast.native_mod_index_entry]) {
+ ret none[def];
+ }
+ alt (Option.get(found)) {
+ case (ast.nmie_view_item(?view_item)) {
+ ret found_view_item(e, view_item, ns);
+ }
+ case (ast.nmie_item(?item)) {
+ alt (item.node) {
+ case (ast.native_item_ty(_, ?id)) {
+ if (ns == ns_type) {
+ ret some(ast.def_native_ty(id));
+ }
+ }
+ case (ast.native_item_fn(_, _, _, _, ?id, _)) {
+ if (ns == ns_value) {
+ ret some(ast.def_native_fn(id));
+ }
+ }
+ }
+ }
+ case (_) {}
+ }
+ ret none[def];
}
-fn resolve_crate(session.session sess, @ast.crate crate) -> @ast.crate {
-
- let fold.ast_fold[env] fld = fold.new_identity_fold[env]();
-
- auto new_crate = resolve_imports(sess, crate);
-
- fld = @rec( fold_pat_tag = bind fold_pat_tag(_,_,_,_,_,_),
- fold_expr_path = bind fold_expr_path(_,_,_,_,_),
- fold_ty_path = bind fold_ty_path(_,_,_,_),
- update_env_for_crate = bind update_env_for_crate(_,_),
- update_env_for_item = bind update_env_for_item(_,_),
- update_env_for_native_item =
- bind update_env_for_native_item(_,_),
- update_env_for_block = bind update_env_for_block(_,_),
- update_env_for_arm = bind update_env_for_arm(_,_),
- update_env_for_expr = bind update_env_for_expr(_,_)
- with *fld );
-
- auto e = rec(scopes = nil[scope],
- sess = sess);
-
- ret fold.fold_crate[env](e, fld, new_crate);
+// FIXME creader should handle multiple namespaces
+fn check_def_by_ns(def d, namespace ns) -> bool {
+ ret alt (d) {
+ case (ast.def_fn(?id)) { ns == ns_value }
+ case (ast.def_obj(?id)) { ns == ns_value }
+ case (ast.def_obj_field(?id)) { ns == ns_value }
+ case (ast.def_mod(?id)) { true }
+ case (ast.def_native_mod(?id)) { true }
+ case (ast.def_const(?id)) { ns == ns_value }
+ case (ast.def_arg(?id)) { ns == ns_value }
+ case (ast.def_local(?id)) { ns == ns_value }
+ case (ast.def_upvar(?id)) { ns == ns_value }
+ case (ast.def_variant(_, ?id)) { ns == ns_value }
+ case (ast.def_ty(?id)) { ns == ns_type }
+ case (ast.def_binding(?id)) { ns == ns_type }
+ case (ast.def_use(?id)) { true }
+ case (ast.def_native_ty(?id)) { ns == ns_type }
+ case (ast.def_native_fn(?id)) { ns == ns_value }
+ };
}
+fn lookup_external(&env e, int cnum, vec[ident] ids, namespace ns)
+ -> Option.t[def] {
+ auto found = creader.lookup_def(e.sess, cnum, ids);
+ if (found != none[def]) {
+ auto d = Option.get(found);
+ if (!check_def_by_ns(d, ns)) { ret none[def]; }
+ e.ext_map.insert(ast.def_id_of_def(d), ids);
+ }
+ ret found;
+ }
+
// Local Variables:
// mode: rust
// fill-column: 78;
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 8ff1f366..b3a0582a 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -7044,6 +7044,9 @@ fn collect_item_1(&@crate_ctxt ccx, @walk_ctxt wcx, &@ast.item i) {
case (ast.item_mod(?name, ?m, ?mid)) {
ccx.items.insert(mid, i);
}
+ case (ast.item_native_mod(_, _, ?mid)) {
+ ccx.items.insert(mid, i);
+ }
case (ast.item_ty(_, _, _, ?did, _)) {
ccx.items.insert(did, i);
}
diff --git a/src/comp/pretty/pprust.rs b/src/comp/pretty/pprust.rs
index d767672f..ceef6256 100644
--- a/src/comp/pretty/pprust.rs
+++ b/src/comp/pretty/pprust.rs
@@ -846,7 +846,7 @@ fn print_view_item(ps s, @ast.view_item item) {
pclose(s);
}
}
- case (ast.view_item_import(?id,?ids,_,_)) {
+ case (ast.view_item_import(?id,?ids,_)) {
wrd1(s, "import");
if (!Str.eq(id, ids.(Vec.len[str](ids)-1u))) {
wrd1(s, id);