rustc: Make iter_structural_ty() not use the "variants" field in the tag info

This commit is contained in:
Patrick Walton 2011-02-25 17:14:48 -08:00
parent b5081a6a82
commit 9c928fcf8c

View File

@ -1457,13 +1457,11 @@ fn type_of_variant(@crate_ctxt cx, &ast.variant v) -> TypeRef {
ret T_struct(lltys); ret T_struct(lltys);
} }
// Returns the number of variants in a tag. // Returns the variants in a tag.
fn tag_variant_count(@crate_ctxt cx, ast.def_id id) -> uint { fn tag_variants(@crate_ctxt cx, ast.def_id id) -> vec[ast.variant] {
check (cx.items.contains_key(id)); check (cx.items.contains_key(id));
alt (cx.items.get(id).node) { alt (cx.items.get(id).node) {
case (ast.item_tag(_, ?variants, _, _)) { case (ast.item_tag(_, ?variants, _, _)) { ret variants; }
ret _vec.len[ast.variant](variants);
}
} }
fail; // not reached fail; // not reached
} }
@ -1519,21 +1517,9 @@ fn iter_structural_ty(@block_ctxt cx,
case (ty.ty_tag(?tid, ?tps)) { case (ty.ty_tag(?tid, ?tps)) {
check (cx.fcx.ccx.tags.contains_key(tid)); check (cx.fcx.ccx.tags.contains_key(tid));
auto info = cx.fcx.ccx.tags.get(tid); auto info = cx.fcx.ccx.tags.get(tid);
auto n_variants = tag_variant_count(cx.fcx.ccx, tid);
// Look up the tag in the typechecked AST. auto variants = tag_variants(cx.fcx.ccx, tid);
check (cx.fcx.ccx.items.contains_key(tid)); auto n_variants = _vec.len[ast.variant](variants);
auto tag_item = cx.fcx.ccx.items.get(tid);
let vec[ast.variant] variants = vec(); // FIXME: typestate bug
alt (tag_item.node) {
case (ast.item_tag(_, ?vs, _, _)) {
variants = vs;
}
case (_) {
log "trans: ty_tag doesn't actually refer to a tag";
fail;
}
}
auto lldiscrim_ptr = cx.build.GEP(v, vec(C_int(0), C_int(0))); auto lldiscrim_ptr = cx.build.GEP(v, vec(C_int(0), C_int(0)));
auto llunion_ptr = cx.build.GEP(v, vec(C_int(0), C_int(1))); auto llunion_ptr = cx.build.GEP(v, vec(C_int(0), C_int(1)));
@ -1548,55 +1534,49 @@ fn iter_structural_ty(@block_ctxt cx,
auto next_cx = new_sub_block_ctxt(cx, "tag-iter-next"); auto next_cx = new_sub_block_ctxt(cx, "tag-iter-next");
auto i = 0u; auto i = 0u;
for (tup(ast.def_id,arity) variant in info.variants) { for (ast.variant variant in variants) {
auto variant_cx = new_sub_block_ctxt(cx, "tag-iter-variant-" + auto variant_cx = new_sub_block_ctxt(cx, "tag-iter-variant-" +
_uint.to_str(i, 10u)); _uint.to_str(i, 10u));
llvm.LLVMAddCase(llswitch, C_int(i as int), variant_cx.llbb); llvm.LLVMAddCase(llswitch, C_int(i as int), variant_cx.llbb);
alt (variant._1) { if (_vec.len[ast.variant_arg](variant.args) > 0u) {
case (n_ary) { // N-ary variant.
let vec[ValueRef] vals = vec(C_int(0), C_int(1), let vec[ValueRef] vals = vec(C_int(0), C_int(1),
C_int(i as int)); C_int(i as int));
auto llvar = variant_cx.build.GEP(v, vals); auto llvar = variant_cx.build.GEP(v, vals);
auto llvarty = type_of_variant(cx.fcx.ccx, auto llvarty = type_of_variant(cx.fcx.ccx, variants.(i));
variants.(i));
auto fn_ty = ty.ann_to_type(variants.(i).ann); auto fn_ty = ty.ann_to_type(variants.(i).ann);
alt (fn_ty.struct) { alt (fn_ty.struct) {
case (ty.ty_fn(_, ?args, _)) { case (ty.ty_fn(_, ?args, _)) {
auto llvarp = variant_cx.build. auto llvarp = variant_cx.build.
TruncOrBitCast(llunion_ptr, TruncOrBitCast(llunion_ptr, T_ptr(llvarty));
T_ptr(llvarty));
auto j = 0u; auto j = 0u;
for (ty.arg a in args) { for (ty.arg a in args) {
auto v = vec(C_int(0), auto v = vec(C_int(0), C_int(j as int));
C_int(j as int)); auto llfldp = variant_cx.build.GEP(llvarp, v);
auto llfldp =
variant_cx.build.GEP(llvarp, v);
auto ty_subst = ty.substitute_ty_params( auto ty_subst = ty.substitute_ty_params(
info.ty_params, tps, a.ty); info.ty_params, tps, a.ty);
auto llfld = auto llfld =
load_scalar_or_boxed(variant_cx, load_scalar_or_boxed(variant_cx,
llfldp, llfldp,
ty_subst); ty_subst);
auto res = f(variant_cx, llfld, ty_subst); auto res = f(variant_cx, llfld, ty_subst);
variant_cx = res.bcx; variant_cx = res.bcx;
j += 1u; j += 1u;
}
} }
case (_) { fail; }
} }
case (_) { fail; }
}
variant_cx.build.Br(next_cx.llbb); variant_cx.build.Br(next_cx.llbb);
} } else {
case (nullary) { // Nullary variant; nothing to do.
// Nothing to do. variant_cx.build.Br(next_cx.llbb);
variant_cx.build.Br(next_cx.llbb);
}
} }
i += 1u; i += 1u;