Keep resolve data in external hash table, rather than embedded defs
One step closer to removing fold and having a single, immutable AST. Resolve still uses fold, because it has to detect and transform expr_field expressions. If we go through on our plan of moving to a different syntax for module dereferencing, the parser can spit out expr_field expressions, and resolve can move to walk. (I am truly sorry for the things I did in typestate_check.rs. I expect we'll want to change that to walk as well in the near future, at which point it should probably pass around a context record, which could hold the def_map.)
This commit is contained in:
parent
2b36e40c58
commit
358a1aeec9
14 changed files with 521 additions and 486 deletions
|
|
@ -7,9 +7,11 @@ import std.Option.none;
|
|||
import std.Int;
|
||||
import std.Vec;
|
||||
import util.common;
|
||||
import resolve.def_map;
|
||||
|
||||
type fn_id_of_local = std.Map.hashmap[ast.def_id, ast.def_id];
|
||||
type env = rec(mutable vec[ast.def_id] current_context, // fn or obj
|
||||
def_map def_map,
|
||||
fn_id_of_local idmap,
|
||||
session.session sess);
|
||||
|
||||
|
|
@ -22,7 +24,7 @@ fn enter_item(@env e, &@ast.item i) {
|
|||
case (ast.item_fn(?name, _, _, ?id, _)) {
|
||||
Vec.push(e.current_context, id);
|
||||
}
|
||||
case (ast.item_obj(_, _, _, ?ids, _)) {
|
||||
case (ast.item_obj(?name, _, _, ?ids, _)) {
|
||||
Vec.push(e.current_context, ids.ty);
|
||||
}
|
||||
case (_) {}
|
||||
|
|
@ -59,15 +61,14 @@ fn walk_expr(@env e, &@ast.expr x) {
|
|||
case (_) { }
|
||||
}
|
||||
}
|
||||
case (ast.expr_path(_, ?def, _)) {
|
||||
case (ast.expr_path(?pt, ?ann)) {
|
||||
auto local_id;
|
||||
alt (Option.get(def)) {
|
||||
alt (e.def_map.get(ast.ann_tag(ann))) {
|
||||
case (ast.def_local(?id)) { local_id = id; }
|
||||
case (_) { ret; }
|
||||
}
|
||||
|
||||
auto df = ast.def_id_of_def(Option.get(def));
|
||||
auto def_context = Option.get(e.idmap.find(df));
|
||||
auto df = ast.def_id_of_def(e.def_map.get(ast.ann_tag(ann)));
|
||||
auto def_context = e.idmap.get(df);
|
||||
|
||||
if (current_context(*e) != def_context) {
|
||||
e.sess.span_err(x.span,
|
||||
|
|
@ -94,9 +95,10 @@ fn walk_block(@env e, &ast.block b) {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_for_captures(session.session sess, @ast.crate crate) {
|
||||
fn check_for_captures(session.session sess, @ast.crate crate, def_map dm) {
|
||||
let vec[ast.def_id] curctx = vec();
|
||||
auto env = @rec(mutable current_context = curctx,
|
||||
def_map = dm,
|
||||
idmap = common.new_def_hash[ast.def_id](),
|
||||
sess = sess);
|
||||
auto visitor = rec(visit_item_pre = bind enter_item(env, _),
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ type ast_fold[ENV] =
|
|||
&@ty output) -> @ty) fold_ty_fn,
|
||||
|
||||
(fn(&ENV e, &span sp, &ast.path p,
|
||||
&Option.t[def] d) -> @ty) fold_ty_path,
|
||||
&ann a) -> @ty) fold_ty_path,
|
||||
|
||||
(fn(&ENV e, &span sp, &@ty t) -> @ty) fold_ty_chan,
|
||||
(fn(&ENV e, &span sp, &@ty t) -> @ty) fold_ty_port,
|
||||
|
|
@ -171,7 +171,6 @@ type ast_fold[ENV] =
|
|||
|
||||
(fn(&ENV e, &span sp,
|
||||
&path p,
|
||||
&Option.t[def] d,
|
||||
&ann a) -> @expr) fold_expr_path,
|
||||
|
||||
(fn(&ENV e, &span sp,
|
||||
|
|
@ -231,7 +230,6 @@ type ast_fold[ENV] =
|
|||
|
||||
(fn(&ENV e, &span sp,
|
||||
&path p, &vec[@pat] args,
|
||||
&Option.t[ast.variant_def] d,
|
||||
&ann a) -> @pat) fold_pat_tag,
|
||||
|
||||
|
||||
|
|
@ -419,9 +417,9 @@ fn fold_ty[ENV](&ENV env, &ast_fold[ENV] fld, &@ty t) -> @ty {
|
|||
ret fld.fold_ty_obj(env_, t.span, meths_);
|
||||
}
|
||||
|
||||
case (ast.ty_path(?pth, ?ref_opt)) {
|
||||
case (ast.ty_path(?pth, ?ann)) {
|
||||
auto pth_ = fold_path(env, fld, pth);
|
||||
ret fld.fold_ty_path(env_, t.span, pth_, ref_opt);
|
||||
ret fld.fold_ty_path(env_, t.span, pth_, ann);
|
||||
}
|
||||
|
||||
case (ast.ty_fn(?proto, ?inputs, ?output)) {
|
||||
|
|
@ -508,7 +506,7 @@ fn fold_pat[ENV](&ENV env, &ast_fold[ENV] fld, &@ast.pat p) -> @ast.pat {
|
|||
case (ast.pat_bind(?id, ?did, ?t)) {
|
||||
ret fld.fold_pat_bind(env_, p.span, id, did, t);
|
||||
}
|
||||
case (ast.pat_tag(?path, ?pats, ?d, ?t)) {
|
||||
case (ast.pat_tag(?path, ?pats, ?t)) {
|
||||
auto ppath = fold_path(env, fld, path);
|
||||
|
||||
let vec[@ast.pat] ppats = vec();
|
||||
|
|
@ -516,7 +514,7 @@ fn fold_pat[ENV](&ENV env, &ast_fold[ENV] fld, &@ast.pat p) -> @ast.pat {
|
|||
ppats += vec(fold_pat(env_, fld, pat));
|
||||
}
|
||||
|
||||
ret fld.fold_pat_tag(env_, p.span, ppath, ppats, d, t);
|
||||
ret fld.fold_pat_tag(env_, p.span, ppath, ppats, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -742,10 +740,10 @@ fn fold_expr[ENV](&ENV env, &ast_fold[ENV] fld, &@expr e) -> @expr {
|
|||
ret fld.fold_expr_index(env_, e.span, ee, iix, t2);
|
||||
}
|
||||
|
||||
case (ast.expr_path(?p, ?r, ?t)) {
|
||||
case (ast.expr_path(?p, ?t)) {
|
||||
auto p_ = fold_path(env_, fld, p);
|
||||
auto t2 = fld.fold_ann(env_, t);
|
||||
ret fld.fold_expr_path(env_, e.span, p_, r, t2);
|
||||
ret fld.fold_expr_path(env_, e.span, p_, t2);
|
||||
}
|
||||
|
||||
case (ast.expr_ext(?p, ?args, ?body, ?expanded, ?t)) {
|
||||
|
|
@ -1201,8 +1199,8 @@ fn identity_fold_ty_fn[ENV](&ENV env, &span sp,
|
|||
}
|
||||
|
||||
fn identity_fold_ty_path[ENV](&ENV env, &span sp, &ast.path p,
|
||||
&Option.t[def] d) -> @ty {
|
||||
ret @respan(sp, ast.ty_path(p, d));
|
||||
&ann a) -> @ty {
|
||||
ret @respan(sp, ast.ty_path(p, a));
|
||||
}
|
||||
|
||||
fn identity_fold_ty_chan[ENV](&ENV env, &span sp, &@ty t) -> @ty {
|
||||
|
|
@ -1349,9 +1347,8 @@ fn identity_fold_expr_index[ENV](&ENV env, &span sp,
|
|||
}
|
||||
|
||||
fn identity_fold_expr_path[ENV](&ENV env, &span sp,
|
||||
&path p, &Option.t[def] d,
|
||||
&ann a) -> @expr {
|
||||
ret @respan(sp, ast.expr_path(p, d, a));
|
||||
&path p, &ann a) -> @expr {
|
||||
ret @respan(sp, ast.expr_path(p, a));
|
||||
}
|
||||
|
||||
fn identity_fold_expr_ext[ENV](&ENV env, &span sp,
|
||||
|
|
@ -1443,8 +1440,8 @@ fn identity_fold_pat_bind[ENV](&ENV e, &span sp, &ident i,
|
|||
}
|
||||
|
||||
fn identity_fold_pat_tag[ENV](&ENV e, &span sp, &path p, &vec[@pat] args,
|
||||
&Option.t[ast.variant_def] d, &ann a) -> @pat {
|
||||
ret @respan(sp, ast.pat_tag(p, args, d, a));
|
||||
&ann a) -> @pat {
|
||||
ret @respan(sp, ast.pat_tag(p, args, a));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1692,7 +1689,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
|
|||
fold_expr_recv = bind identity_fold_expr_recv[ENV](_,_,_,_,_),
|
||||
fold_expr_field = bind identity_fold_expr_field[ENV](_,_,_,_,_),
|
||||
fold_expr_index = bind identity_fold_expr_index[ENV](_,_,_,_,_),
|
||||
fold_expr_path = bind identity_fold_expr_path[ENV](_,_,_,_,_),
|
||||
fold_expr_path = bind identity_fold_expr_path[ENV](_,_,_,_),
|
||||
fold_expr_ext = bind identity_fold_expr_ext[ENV](_,_,_,_,_,_,_),
|
||||
fold_expr_fail = bind identity_fold_expr_fail[ENV](_,_,_),
|
||||
fold_expr_break = bind identity_fold_expr_break[ENV](_,_,_),
|
||||
|
|
@ -1715,7 +1712,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
|
|||
fold_pat_wild = bind identity_fold_pat_wild[ENV](_,_,_),
|
||||
fold_pat_lit = bind identity_fold_pat_lit[ENV](_,_,_,_),
|
||||
fold_pat_bind = bind identity_fold_pat_bind[ENV](_,_,_,_,_),
|
||||
fold_pat_tag = bind identity_fold_pat_tag[ENV](_,_,_,_,_,_),
|
||||
fold_pat_tag = bind identity_fold_pat_tag[ENV](_,_,_,_,_),
|
||||
|
||||
fold_stmt_decl = bind identity_fold_stmt_decl[ENV](_,_,_,_),
|
||||
fold_stmt_expr = bind identity_fold_stmt_expr[ENV](_,_,_,_),
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import front.creader;
|
|||
import driver.session.session;
|
||||
import util.common.new_def_hash;
|
||||
import util.common.new_int_hash;
|
||||
import util.common.new_uint_hash;
|
||||
import util.common.new_str_hash;
|
||||
import util.common.span;
|
||||
import util.typestate_ann.ts_ann;
|
||||
|
|
@ -74,7 +75,10 @@ tag native_mod_index_entry {
|
|||
type nmod_index = hashmap[ident,native_mod_index_entry];
|
||||
type indexed_nmod = rec(ast.native_mod m, nmod_index index);
|
||||
|
||||
type env = rec(hashmap[ast.def_num,import_state] imports,
|
||||
type def_map = hashmap[uint,def];
|
||||
|
||||
type env = rec(def_map def_map,
|
||||
hashmap[ast.def_num,import_state] imports,
|
||||
hashmap[ast.def_num,@indexed_mod] mod_map,
|
||||
hashmap[ast.def_num,@indexed_nmod] nmod_map,
|
||||
hashmap[def_id,vec[ident]] ext_map,
|
||||
|
|
@ -90,8 +94,10 @@ tag namespace {
|
|||
ns_type;
|
||||
}
|
||||
|
||||
fn resolve_crate(session sess, @ast.crate crate) -> @ast.crate {
|
||||
auto e = @rec(imports = new_int_hash[import_state](),
|
||||
fn resolve_crate(session sess, @ast.crate crate)
|
||||
-> tup(@ast.crate, def_map) {
|
||||
auto e = @rec(def_map = new_uint_hash[def](),
|
||||
imports = new_int_hash[import_state](),
|
||||
mod_map = new_int_hash[@indexed_mod](),
|
||||
nmod_map = new_int_hash[@indexed_nmod](),
|
||||
ext_map = new_def_hash[vec[ident]](),
|
||||
|
|
@ -99,7 +105,7 @@ fn resolve_crate(session sess, @ast.crate crate) -> @ast.crate {
|
|||
sess = sess);
|
||||
map_crate(e, *crate);
|
||||
resolve_imports(*e);
|
||||
ret resolve_names(e, *crate);
|
||||
ret tup(resolve_names(e, *crate), e.def_map);
|
||||
}
|
||||
|
||||
// Locate all modules and imports and index them, so that the next passes can
|
||||
|
|
@ -165,8 +171,8 @@ fn resolve_imports(&env e) {
|
|||
}
|
||||
|
||||
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,_,_,_,_,_),
|
||||
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(_,_),
|
||||
|
|
@ -291,8 +297,8 @@ fn resolve_import(&env e, &@ast.view_item it, &list[scope] sc) {
|
|||
// and split that off as the 'primary' expr_path, with secondary expr_field
|
||||
// expressions tacked on the end.
|
||||
|
||||
fn fold_expr_path(@env e, &list[scope] sc, &span sp, &ast.path p,
|
||||
&Option.t[def] d, &ann a) -> @ast.expr {
|
||||
fn fold_expr_path(@env e, &list[scope] sc, &span sp, &ast.path p, &ann a)
|
||||
-> @ast.expr {
|
||||
auto idents = p.node.idents;
|
||||
auto n_idents = Vec.len(idents);
|
||||
assert (n_idents != 0u);
|
||||
|
|
@ -310,7 +316,10 @@ fn fold_expr_path(@env e, &list[scope] sc, &span sp, &ast.path p,
|
|||
}
|
||||
|
||||
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));
|
||||
auto ex = @fold.respan(sp, ast.expr_path(p, a));
|
||||
e.def_map.insert(ast.ann_tag(a), dcur);
|
||||
// FIXME this duplicates the ann. Is that a problem? How will we deal with
|
||||
// splitting this into path and field exprs when we don't fold?
|
||||
while (i < n_idents) {
|
||||
ex = @fold.respan(sp, ast.expr_field(ex, idents.(i), a));
|
||||
i += 1u;
|
||||
|
|
@ -319,33 +328,12 @@ fn fold_expr_path(@env e, &list[scope] sc, &span sp, &ast.path p,
|
|||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
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 {
|
||||
&vec[@ast.pat] args, &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));
|
||||
e.def_map.insert(ast.ann_tag(a), ast.def_variant(did, vid));
|
||||
ret @fold.respan[ast.pat_](sp, ast.pat_tag(p, args, a));
|
||||
}
|
||||
case (_) {
|
||||
e.sess.span_err(sp, "not a tag variant: " +
|
||||
|
|
@ -356,9 +344,10 @@ fn fold_pat_tag(@env e, &list[scope] sc, &span sp, &ast.path p,
|
|||
}
|
||||
|
||||
fn fold_ty_path(@env e, &list[scope] sc, &span sp, &ast.path p,
|
||||
&Option.t[def] d) -> @ast.ty {
|
||||
&ast.ann a) -> @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)));
|
||||
e.def_map.insert(ast.ann_tag(a), new_def);
|
||||
ret @fold.respan[ast.ty_](sp, ast.ty_path(p, a));
|
||||
}
|
||||
|
||||
fn is_module(def d) -> bool {
|
||||
|
|
@ -380,6 +369,26 @@ fn unresolved(&env e, &span sp, ident id, str kind) {
|
|||
e.sess.span_err(sp, "unresolved " + kind + ": " + id);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
if (is_module(dcur)) {
|
||||
e.sess.span_err(sp, Str.connect(idents, ".") +
|
||||
" is a module, not a " + ns_name(ns));
|
||||
}
|
||||
ret dcur;
|
||||
}
|
||||
|
||||
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)) {
|
||||
|
|
@ -497,7 +506,7 @@ fn lookup_in_pat(ident id, &ast.pat pat) -> Option.t[def] {
|
|||
}
|
||||
case (ast.pat_wild(_)) {}
|
||||
case (ast.pat_lit(_, _)) {}
|
||||
case (ast.pat_tag(_, ?pats, _, _)) {
|
||||
case (ast.pat_tag(_, ?pats, _)) {
|
||||
for (@ast.pat p in pats) {
|
||||
auto found = lookup_in_pat(id, *p);
|
||||
if (found != none[def]) { ret found; }
|
||||
|
|
|
|||
|
|
@ -3621,13 +3621,14 @@ fn collect_upvars(&@block_ctxt cx, &ast.block bloc, &ast.def_id initial_decl)
|
|||
-> vec[ast.def_id] {
|
||||
type env = @rec(
|
||||
mutable vec[ast.def_id] refs,
|
||||
hashmap[ast.def_id,()] decls
|
||||
hashmap[ast.def_id,()] decls,
|
||||
resolve.def_map def_map
|
||||
);
|
||||
|
||||
fn walk_expr(env e, &@ast.expr expr) {
|
||||
alt (expr.node) {
|
||||
case (ast.expr_path(?path, ?d, _)) {
|
||||
alt (Option.get[ast.def](d)) {
|
||||
case (ast.expr_path(?path, ?ann)) {
|
||||
alt (e.def_map.get(ast.ann_tag(ann))) {
|
||||
case (ast.def_arg(?did)) {
|
||||
Vec.push[ast.def_id](e.refs, did);
|
||||
}
|
||||
|
|
@ -3656,7 +3657,9 @@ fn collect_upvars(&@block_ctxt cx, &ast.block bloc, &ast.def_id initial_decl)
|
|||
let vec[ast.def_id] refs = vec();
|
||||
let hashmap[ast.def_id,()] decls = new_def_hash[()]();
|
||||
decls.insert(initial_decl, ());
|
||||
let env e = @rec(mutable refs=refs, decls=decls);
|
||||
let env e = @rec(mutable refs=refs,
|
||||
decls=decls,
|
||||
def_map=cx.fcx.lcx.ccx.tcx.def_map);
|
||||
|
||||
auto visitor = @rec(visit_decl_pre = bind walk_decl(e, _),
|
||||
visit_expr_pre = bind walk_expr(e, _)
|
||||
|
|
@ -3941,7 +3944,7 @@ fn trans_pat_match(&@block_ctxt cx, &@ast.pat pat, ValueRef llval,
|
|||
ret res(matched_cx, llval);
|
||||
}
|
||||
|
||||
case (ast.pat_tag(?id, ?subpats, ?vdef_opt, ?ann)) {
|
||||
case (ast.pat_tag(?id, ?subpats, ?ann)) {
|
||||
auto lltagptr = cx.build.PointerCast(llval,
|
||||
T_opaque_tag_ptr(cx.fcx.lcx.ccx.tn));
|
||||
|
||||
|
|
@ -3949,16 +3952,16 @@ fn trans_pat_match(&@block_ctxt cx, &@ast.pat pat, ValueRef llval,
|
|||
vec(C_int(0), C_int(0)));
|
||||
auto lldiscrim = cx.build.Load(lldiscrimptr);
|
||||
|
||||
auto vdef = Option.get[ast.variant_def](vdef_opt);
|
||||
auto variant_id = vdef._1;
|
||||
auto vdef = ast.variant_def_ids
|
||||
(cx.fcx.lcx.ccx.tcx.def_map.get(ast.ann_tag(ann)));
|
||||
auto variant_tag = 0;
|
||||
|
||||
auto variants = tag_variants(cx.fcx.lcx.ccx, vdef._0);
|
||||
auto i = 0;
|
||||
for (variant_info v in variants) {
|
||||
auto this_variant_id = v.id;
|
||||
if (variant_id._0 == this_variant_id._0 &&
|
||||
variant_id._1 == this_variant_id._1) {
|
||||
if (vdef._1._0 == this_variant_id._0 &&
|
||||
vdef._1._1 == this_variant_id._1) {
|
||||
variant_tag = i;
|
||||
}
|
||||
i += 1;
|
||||
|
|
@ -4021,11 +4024,12 @@ fn trans_pat_binding(&@block_ctxt cx, &@ast.pat pat,
|
|||
ret copy_ty(bcx, INIT, dst, llval, t);
|
||||
}
|
||||
}
|
||||
case (ast.pat_tag(_, ?subpats, ?vdef_opt, ?ann)) {
|
||||
case (ast.pat_tag(_, ?subpats, ?ann)) {
|
||||
if (Vec.len[@ast.pat](subpats) == 0u) { ret res(cx, llval); }
|
||||
|
||||
// Get the appropriate variant for this tag.
|
||||
auto vdef = Option.get[ast.variant_def](vdef_opt);
|
||||
auto vdef = ast.variant_def_ids
|
||||
(cx.fcx.lcx.ccx.tcx.def_map.get(ast.ann_tag(ann)));
|
||||
|
||||
auto lltagptr = cx.build.PointerCast(llval,
|
||||
T_opaque_tag_ptr(cx.fcx.lcx.ccx.tn));
|
||||
|
|
@ -4191,109 +4195,103 @@ fn lookup_discriminant(&@local_ctxt lcx, &ast.def_id tid, &ast.def_id vid)
|
|||
}
|
||||
}
|
||||
|
||||
fn trans_path(&@block_ctxt cx, &ast.path p, &Option.t[ast.def] dopt,
|
||||
&ast.ann ann) -> lval_result {
|
||||
alt (dopt) {
|
||||
case (some[ast.def](?def)) {
|
||||
alt (def) {
|
||||
case (ast.def_arg(?did)) {
|
||||
alt (cx.fcx.llargs.find(did)) {
|
||||
case (none[ValueRef]) {
|
||||
assert (cx.fcx.llupvars.contains_key(did));
|
||||
ret lval_mem(cx, cx.fcx.llupvars.get(did));
|
||||
}
|
||||
case (some[ValueRef](?llval)) {
|
||||
ret lval_mem(cx, llval);
|
||||
}
|
||||
}
|
||||
fn trans_path(&@block_ctxt cx, &ast.path p, &ast.ann ann) -> lval_result {
|
||||
alt (cx.fcx.lcx.ccx.tcx.def_map.get(ast.ann_tag(ann))) {
|
||||
case (ast.def_arg(?did)) {
|
||||
alt (cx.fcx.llargs.find(did)) {
|
||||
case (none[ValueRef]) {
|
||||
assert (cx.fcx.llupvars.contains_key(did));
|
||||
ret lval_mem(cx, cx.fcx.llupvars.get(did));
|
||||
}
|
||||
case (ast.def_local(?did)) {
|
||||
alt (cx.fcx.lllocals.find(did)) {
|
||||
case (none[ValueRef]) {
|
||||
assert (cx.fcx.llupvars.contains_key(did));
|
||||
ret lval_mem(cx, cx.fcx.llupvars.get(did));
|
||||
}
|
||||
case (some[ValueRef](?llval)) {
|
||||
ret lval_mem(cx, llval);
|
||||
}
|
||||
}
|
||||
}
|
||||
case (ast.def_binding(?did)) {
|
||||
assert (cx.fcx.lllocals.contains_key(did));
|
||||
ret lval_mem(cx, cx.fcx.lllocals.get(did));
|
||||
}
|
||||
case (ast.def_obj_field(?did)) {
|
||||
assert (cx.fcx.llobjfields.contains_key(did));
|
||||
ret lval_mem(cx, cx.fcx.llobjfields.get(did));
|
||||
}
|
||||
case (ast.def_fn(?did)) {
|
||||
auto tyt = ty.lookup_item_type(cx.fcx.lcx.ccx.sess,
|
||||
cx.fcx.lcx.ccx.tcx, cx.fcx.lcx.ccx.type_cache, did);
|
||||
ret lval_generic_fn(cx, tyt, did, ann);
|
||||
}
|
||||
case (ast.def_obj(?did)) {
|
||||
auto tyt = ty.lookup_item_type(cx.fcx.lcx.ccx.sess,
|
||||
cx.fcx.lcx.ccx.tcx, cx.fcx.lcx.ccx.type_cache, did);
|
||||
ret lval_generic_fn(cx, tyt, did, ann);
|
||||
}
|
||||
case (ast.def_variant(?tid, ?vid)) {
|
||||
auto v_tyt = ty.lookup_item_type(cx.fcx.lcx.ccx.sess,
|
||||
cx.fcx.lcx.ccx.tcx, cx.fcx.lcx.ccx.type_cache, vid);
|
||||
alt (ty.struct(cx.fcx.lcx.ccx.tcx, v_tyt._1)) {
|
||||
case (ty.ty_fn(_, _, _)) {
|
||||
// N-ary variant.
|
||||
ret lval_generic_fn(cx, v_tyt, vid, ann);
|
||||
}
|
||||
case (_) {
|
||||
// Nullary variant.
|
||||
auto tag_ty = node_ann_type(cx.fcx.lcx.ccx, ann);
|
||||
auto lldiscrim_gv =
|
||||
lookup_discriminant(cx.fcx.lcx, tid, vid);
|
||||
auto lldiscrim = cx.build.Load(lldiscrim_gv);
|
||||
|
||||
auto alloc_result = alloc_ty(cx, tag_ty);
|
||||
auto lltagblob = alloc_result.val;
|
||||
|
||||
auto lltagty;
|
||||
if (ty.type_has_dynamic_size(cx.fcx.lcx.ccx.tcx,
|
||||
tag_ty)) {
|
||||
lltagty = T_opaque_tag(cx.fcx.lcx.ccx.tn);
|
||||
} else {
|
||||
lltagty = type_of(cx.fcx.lcx.ccx, tag_ty);
|
||||
}
|
||||
auto lltagptr = alloc_result.bcx.build.
|
||||
PointerCast(lltagblob, T_ptr(lltagty));
|
||||
|
||||
auto lldiscrimptr = alloc_result.bcx.build.GEP(
|
||||
lltagptr, vec(C_int(0), C_int(0)));
|
||||
alloc_result.bcx.build.Store(lldiscrim,
|
||||
lldiscrimptr);
|
||||
|
||||
ret lval_val(alloc_result.bcx, lltagptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
case (ast.def_const(?did)) {
|
||||
// TODO: externals
|
||||
assert (cx.fcx.lcx.ccx.consts.contains_key(did));
|
||||
ret lval_mem(cx, cx.fcx.lcx.ccx.consts.get(did));
|
||||
}
|
||||
case (ast.def_native_fn(?did)) {
|
||||
auto tyt = ty.lookup_item_type(cx.fcx.lcx.ccx.sess,
|
||||
cx.fcx.lcx.ccx.tcx,
|
||||
cx.fcx.lcx.ccx.type_cache, did);
|
||||
ret lval_generic_fn(cx, tyt, did, ann);
|
||||
}
|
||||
case (_) {
|
||||
cx.fcx.lcx.ccx.sess.unimpl("def variant in trans");
|
||||
case (some[ValueRef](?llval)) {
|
||||
ret lval_mem(cx, llval);
|
||||
}
|
||||
}
|
||||
}
|
||||
case (none[ast.def]) {
|
||||
cx.fcx.lcx.ccx.sess.err("unresolved expr_path in trans");
|
||||
case (ast.def_local(?did)) {
|
||||
alt (cx.fcx.lllocals.find(did)) {
|
||||
case (none[ValueRef]) {
|
||||
assert (cx.fcx.llupvars.contains_key(did));
|
||||
ret lval_mem(cx, cx.fcx.llupvars.get(did));
|
||||
}
|
||||
case (some[ValueRef](?llval)) {
|
||||
ret lval_mem(cx, llval);
|
||||
}
|
||||
}
|
||||
}
|
||||
case (ast.def_binding(?did)) {
|
||||
assert (cx.fcx.lllocals.contains_key(did));
|
||||
ret lval_mem(cx, cx.fcx.lllocals.get(did));
|
||||
}
|
||||
case (ast.def_obj_field(?did)) {
|
||||
assert (cx.fcx.llobjfields.contains_key(did));
|
||||
ret lval_mem(cx, cx.fcx.llobjfields.get(did));
|
||||
}
|
||||
case (ast.def_fn(?did)) {
|
||||
auto tyt = ty.lookup_item_type(cx.fcx.lcx.ccx.sess,
|
||||
cx.fcx.lcx.ccx.tcx,
|
||||
cx.fcx.lcx.ccx.type_cache, did);
|
||||
ret lval_generic_fn(cx, tyt, did, ann);
|
||||
}
|
||||
case (ast.def_obj(?did)) {
|
||||
auto tyt = ty.lookup_item_type(cx.fcx.lcx.ccx.sess,
|
||||
cx.fcx.lcx.ccx.tcx,
|
||||
cx.fcx.lcx.ccx.type_cache, did);
|
||||
ret lval_generic_fn(cx, tyt, did, ann);
|
||||
}
|
||||
case (ast.def_variant(?tid, ?vid)) {
|
||||
auto v_tyt = ty.lookup_item_type(cx.fcx.lcx.ccx.sess,
|
||||
cx.fcx.lcx.ccx.tcx,
|
||||
cx.fcx.lcx.ccx.type_cache, vid);
|
||||
alt (ty.struct(cx.fcx.lcx.ccx.tcx, v_tyt._1)) {
|
||||
case (ty.ty_fn(_, _, _)) {
|
||||
// N-ary variant.
|
||||
ret lval_generic_fn(cx, v_tyt, vid, ann);
|
||||
}
|
||||
case (_) {
|
||||
// Nullary variant.
|
||||
auto tag_ty = node_ann_type(cx.fcx.lcx.ccx, ann);
|
||||
auto lldiscrim_gv =
|
||||
lookup_discriminant(cx.fcx.lcx, tid, vid);
|
||||
auto lldiscrim = cx.build.Load(lldiscrim_gv);
|
||||
|
||||
auto alloc_result = alloc_ty(cx, tag_ty);
|
||||
auto lltagblob = alloc_result.val;
|
||||
|
||||
auto lltagty;
|
||||
if (ty.type_has_dynamic_size(cx.fcx.lcx.ccx.tcx,
|
||||
tag_ty)) {
|
||||
lltagty = T_opaque_tag(cx.fcx.lcx.ccx.tn);
|
||||
} else {
|
||||
lltagty = type_of(cx.fcx.lcx.ccx, tag_ty);
|
||||
}
|
||||
auto lltagptr = alloc_result.bcx.build.
|
||||
PointerCast(lltagblob, T_ptr(lltagty));
|
||||
|
||||
auto lldiscrimptr = alloc_result.bcx.build.GEP
|
||||
(lltagptr, vec(C_int(0), C_int(0)));
|
||||
alloc_result.bcx.build.Store(lldiscrim,
|
||||
lldiscrimptr);
|
||||
|
||||
ret lval_val(alloc_result.bcx, lltagptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
case (ast.def_const(?did)) {
|
||||
// TODO: externals
|
||||
assert (cx.fcx.lcx.ccx.consts.contains_key(did));
|
||||
ret lval_mem(cx, cx.fcx.lcx.ccx.consts.get(did));
|
||||
}
|
||||
case (ast.def_native_fn(?did)) {
|
||||
auto tyt = ty.lookup_item_type(cx.fcx.lcx.ccx.sess,
|
||||
cx.fcx.lcx.ccx.tcx,
|
||||
cx.fcx.lcx.ccx.type_cache, did);
|
||||
ret lval_generic_fn(cx, tyt, did, ann);
|
||||
}
|
||||
case (_) {
|
||||
cx.fcx.lcx.ccx.sess.unimpl("def variant in trans");
|
||||
}
|
||||
}
|
||||
fail;
|
||||
}
|
||||
|
||||
fn trans_field(&@block_ctxt cx, &ast.span sp, ValueRef v, &ty.t t0,
|
||||
|
|
@ -4402,8 +4400,8 @@ fn trans_index(&@block_ctxt cx, &ast.span sp, &@ast.expr base,
|
|||
|
||||
fn trans_lval(&@block_ctxt cx, &@ast.expr e) -> lval_result {
|
||||
alt (e.node) {
|
||||
case (ast.expr_path(?p, ?dopt, ?ann)) {
|
||||
ret trans_path(cx, p, dopt, ann);
|
||||
case (ast.expr_path(?p, ?ann)) {
|
||||
ret trans_path(cx, p, ann);
|
||||
}
|
||||
case (ast.expr_field(?base, ?ident, ?ann)) {
|
||||
auto r = trans_expr(cx, base);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ type mt = rec(t ty, ast.mutability mut);
|
|||
type creader_cache = hashmap[tup(int,uint,uint),ty.t];
|
||||
type ctxt = rec(@type_store ts,
|
||||
session.session sess,
|
||||
resolve.def_map def_map,
|
||||
creader_cache rcache,
|
||||
hashmap[t,str] short_names_cache);
|
||||
type ty_ctxt = ctxt; // Needed for disambiguation from Unify.ctxt.
|
||||
|
|
@ -209,9 +210,10 @@ fn mk_rcache() -> creader_cache {
|
|||
ret Map.mk_hashmap[tup(int,uint,uint),t](h, e);
|
||||
}
|
||||
|
||||
fn mk_ctxt(session.session s) -> ctxt {
|
||||
fn mk_ctxt(session.session s, resolve.def_map dm) -> ctxt {
|
||||
ret rec(ts = mk_type_store(),
|
||||
sess = s,
|
||||
def_map = dm,
|
||||
rcache = mk_rcache(),
|
||||
short_names_cache =
|
||||
Map.mk_hashmap[ty.t,str](ty.hash_ty, ty.eq_ty));
|
||||
|
|
@ -1640,7 +1642,7 @@ fn pat_ty(&ctxt cx, &@ast.pat pat) -> t {
|
|||
case (ast.pat_wild(?ann)) { ret ann_to_monotype(cx, ann); }
|
||||
case (ast.pat_lit(_, ?ann)) { ret ann_to_monotype(cx, ann); }
|
||||
case (ast.pat_bind(_, _, ?ann)) { ret ann_to_monotype(cx, ann); }
|
||||
case (ast.pat_tag(_, _, _, ?ann)) { ret ann_to_monotype(cx, ann); }
|
||||
case (ast.pat_tag(_, _, ?ann)) { ret ann_to_monotype(cx, ann); }
|
||||
}
|
||||
fail; // not reached
|
||||
}
|
||||
|
|
@ -1713,7 +1715,7 @@ fn expr_ann(&@ast.expr e) -> ast.ann {
|
|||
case (ast.expr_index(_,_,?a)) {
|
||||
ret a;
|
||||
}
|
||||
case (ast.expr_path(_,_,?a)) {
|
||||
case (ast.expr_path(_,?a)) {
|
||||
ret a;
|
||||
}
|
||||
case (ast.expr_ext(_,_,_,_,?a)) {
|
||||
|
|
@ -1816,9 +1818,9 @@ fn replace_expr_type(&@ast.expr expr,
|
|||
ret @fold.respan(expr.span,
|
||||
ast.expr_field(e, i, mkann(a)));
|
||||
}
|
||||
case (ast.expr_path(?p, ?dopt, ?a)) {
|
||||
case (ast.expr_path(?p, ?a)) {
|
||||
ret @fold.respan(expr.span,
|
||||
ast.expr_path(p, dopt, mkann(a)));
|
||||
ast.expr_path(p, mkann(a)));
|
||||
}
|
||||
case (_) {
|
||||
log_err "unhandled expr type in replace_expr_type(): " +
|
||||
|
|
@ -1897,7 +1899,7 @@ fn is_lval(&@ast.expr expr) -> bool {
|
|||
alt (expr.node) {
|
||||
case (ast.expr_field(_,_,_)) { ret true; }
|
||||
case (ast.expr_index(_,_,_)) { ret true; }
|
||||
case (ast.expr_path(_,_,_)) { ret true; }
|
||||
case (ast.expr_path(_,_)) { ret true; }
|
||||
case (ast.expr_unary(ast.deref,_,_)) { ret true; }
|
||||
case (_) { ret false; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -313,9 +313,8 @@ fn ast_ty_to_ty(&ty.ctxt tcx, &ty_getter getter, &@ast.ty ast_ty) -> ty.t {
|
|||
typ = ty.mk_fn(tcx, proto, i, out_ty);
|
||||
}
|
||||
|
||||
case (ast.ty_path(?path, ?def)) {
|
||||
assert (def != none[ast.def]);
|
||||
alt (Option.get[ast.def](def)) {
|
||||
case (ast.ty_path(?path, ?ann)) {
|
||||
alt (tcx.def_map.get(ast.ann_tag(ann))) {
|
||||
case (ast.def_ty(?id)) {
|
||||
typ = instantiate(tcx, getter, id, path.node.types);
|
||||
}
|
||||
|
|
@ -1137,7 +1136,7 @@ mod Pushdown {
|
|||
none[vec[ty.t]],
|
||||
none[@ts_ann]));
|
||||
}
|
||||
case (ast.pat_tag(?id, ?subpats, ?vdef_opt, ?ann)) {
|
||||
case (ast.pat_tag(?id, ?subpats, ?ann)) {
|
||||
// Take the variant's type parameters out of the expected
|
||||
// type.
|
||||
auto tag_tps;
|
||||
|
|
@ -1150,9 +1149,13 @@ mod Pushdown {
|
|||
}
|
||||
|
||||
// Get the types of the arguments of the variant.
|
||||
auto vdef = Option.get[ast.variant_def](vdef_opt);
|
||||
auto arg_tys = variant_arg_types(fcx.ccx, pat.span, vdef._1,
|
||||
tag_tps);
|
||||
auto arg_tys;
|
||||
alt (fcx.ccx.tcx.def_map.get(ast.ann_tag(ann))) {
|
||||
case (ast.def_variant(_, ?vdefid)) {
|
||||
arg_tys = variant_arg_types(fcx.ccx, pat.span, vdefid,
|
||||
tag_tps);
|
||||
}
|
||||
}
|
||||
|
||||
let vec[@ast.pat] subpats_1 = vec();
|
||||
auto i = 0u;
|
||||
|
|
@ -1162,7 +1165,7 @@ mod Pushdown {
|
|||
}
|
||||
|
||||
// TODO: push down type from "expected".
|
||||
p_1 = ast.pat_tag(id, subpats_1, vdef_opt, ann);
|
||||
p_1 = ast.pat_tag(id, subpats_1, ann);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1387,7 +1390,7 @@ mod Pushdown {
|
|||
ann_to_type(ann), adk);
|
||||
e_1 = ast.expr_index(base, index, triv_ann(ann, t));
|
||||
}
|
||||
case (ast.expr_path(?pth, ?d, ?ann)) {
|
||||
case (ast.expr_path(?pth, ?ann)) {
|
||||
auto tp_substs_0 = ty.ann_to_type_params(ann);
|
||||
auto t_0 = ann_to_type(ann);
|
||||
|
||||
|
|
@ -1416,7 +1419,7 @@ mod Pushdown {
|
|||
}
|
||||
}
|
||||
|
||||
e_1 = ast.expr_path(pth, d,
|
||||
e_1 = ast.expr_path(pth,
|
||||
ast.ann_type(ast.ann_tag(ann), t,
|
||||
ty_params_opt,
|
||||
none[@ts_ann]));
|
||||
|
|
@ -1634,8 +1637,9 @@ fn check_pat(&@fn_ctxt fcx, &@ast.pat pat) -> @ast.pat {
|
|||
auto ann = triv_ann(a, next_ty_var(fcx.ccx));
|
||||
new_pat = ast.pat_bind(id, def_id, ann);
|
||||
}
|
||||
case (ast.pat_tag(?p, ?subpats, ?vdef_opt, ?old_ann)) {
|
||||
auto vdef = Option.get[ast.variant_def](vdef_opt);
|
||||
case (ast.pat_tag(?p, ?subpats, ?old_ann)) {
|
||||
auto vdef = ast.variant_def_ids
|
||||
(fcx.ccx.tcx.def_map.get(ast.ann_tag(old_ann)));
|
||||
auto t = ty.lookup_item_type(fcx.ccx.sess, fcx.ccx.tcx,
|
||||
fcx.ccx.type_cache, vdef._1)._1;
|
||||
auto len = Vec.len[ast.ident](p.node.idents);
|
||||
|
|
@ -1668,7 +1672,7 @@ fn check_pat(&@fn_ctxt fcx, &@ast.pat pat) -> @ast.pat {
|
|||
new_subpats += vec(check_pat(fcx, subpat));
|
||||
}
|
||||
|
||||
new_pat = ast.pat_tag(p, new_subpats, vdef_opt, ann);
|
||||
new_pat = ast.pat_tag(p, new_subpats, ann);
|
||||
}
|
||||
|
||||
// Nullary variants have tag types.
|
||||
|
|
@ -1686,7 +1690,7 @@ fn check_pat(&@fn_ctxt fcx, &@ast.pat pat) -> @ast.pat {
|
|||
fail; // TODO: recover
|
||||
}
|
||||
|
||||
new_pat = ast.pat_tag(p, subpats, vdef_opt, ann);
|
||||
new_pat = ast.pat_tag(p, subpats, ann);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1722,7 +1726,11 @@ fn require_pure_call(@crate_ctxt ccx,
|
|||
}
|
||||
case (ast.pure_fn) {
|
||||
alt (callee.node) {
|
||||
case (ast.expr_path(_, some[ast.def](ast.def_fn(?d_id)), _)) {
|
||||
case (ast.expr_path(_, ?ann)) {
|
||||
auto d_id;
|
||||
alt (ccx.tcx.def_map.get(ast.ann_tag(ann))) {
|
||||
case (ast.def_fn(?_d_id)) { d_id = _d_id; }
|
||||
}
|
||||
alt (get_function_purity(ccx, d_id)) {
|
||||
case (ast.pure_fn) {
|
||||
ret;
|
||||
|
|
@ -1918,10 +1926,9 @@ fn check_expr(&@fn_ctxt fcx, &@ast.expr expr) -> @ast.expr {
|
|||
ast.expr_unary(unop, oper_1, ann));
|
||||
}
|
||||
|
||||
case (ast.expr_path(?pth, ?defopt, ?old_ann)) {
|
||||
case (ast.expr_path(?pth, ?old_ann)) {
|
||||
auto t = ty.mk_nil(fcx.ccx.tcx);
|
||||
assert (defopt != none[ast.def]);
|
||||
auto defn = Option.get[ast.def](defopt);
|
||||
auto defn = fcx.ccx.tcx.def_map.get(ast.ann_tag(old_ann));
|
||||
|
||||
auto tpt = ty_param_count_and_ty_for_def(fcx, expr.span, defn);
|
||||
|
||||
|
|
@ -1929,7 +1936,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast.expr expr) -> @ast.expr {
|
|||
auto ann = instantiate_path(fcx, pth, tpt, expr.span,
|
||||
ast.ann_tag(old_ann));
|
||||
ret @fold.respan[ast.expr_](expr.span,
|
||||
ast.expr_path(pth, defopt, ann));
|
||||
ast.expr_path(pth, ann));
|
||||
}
|
||||
|
||||
// The definition doesn't take type parameters. If the programmer
|
||||
|
|
@ -1940,7 +1947,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast.expr expr) -> @ast.expr {
|
|||
fail;
|
||||
}
|
||||
|
||||
auto e = ast.expr_path(pth, defopt, triv_ann(old_ann, tpt._1));
|
||||
auto e = ast.expr_path(pth, triv_ann(old_ann, tpt._1));
|
||||
ret @fold.respan[ast.expr_](expr.span, e);
|
||||
}
|
||||
|
||||
|
|
@ -2046,9 +2053,11 @@ fn check_expr(&@fn_ctxt fcx, &@ast.expr expr) -> @ast.expr {
|
|||
alt (e.node) {
|
||||
case (ast.expr_call(?operator, ?operands, _)) {
|
||||
alt (operator.node) {
|
||||
case (ast.expr_path(?oper_name,
|
||||
some[ast.def](ast.def_fn(?d_id)), _)) {
|
||||
|
||||
case (ast.expr_path(?oper_name, ?ann)) {
|
||||
auto d_id;
|
||||
alt (fcx.ccx.tcx.def_map.get(ast.ann_tag(ann))) {
|
||||
case (ast.def_fn(?_d_id)) { d_id = _d_id; }
|
||||
}
|
||||
for (@ast.expr operand in operands) {
|
||||
if (! ast.is_constraint_arg(operand)) {
|
||||
fcx.ccx.sess.span_err(expr.span,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -372,7 +372,7 @@ fn walk_expr(&ast_visitor v, @ast.expr e) {
|
|||
walk_expr(v, a);
|
||||
walk_expr(v, b);
|
||||
}
|
||||
case (ast.expr_path(_, _, _)) { }
|
||||
case (ast.expr_path(_, _)) { }
|
||||
case (ast.expr_ext(_, ?args, ?body, ?expansion, _)) {
|
||||
// Only walk expansion, not args/body.
|
||||
walk_expr(v, expansion);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue