Skip to content

Commit 7cfb66c

Browse files
committed
Convert iter_structural_ty to trans::adt
1 parent 936f96a commit 7cfb66c

File tree

1 file changed

+49
-64
lines changed

1 file changed

+49
-64
lines changed

src/librustc/middle/trans/base.rs

Lines changed: 49 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -651,35 +651,16 @@ pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
651651
f: val_and_ty_fn) -> block {
652652
let _icx = cx.insn_ctxt("iter_structural_ty");
653653

654-
fn iter_variant(cx: block, a_tup: ValueRef,
654+
fn iter_variant(cx: block, repr: &adt::Repr, av: ValueRef,
655655
variant: ty::VariantInfo,
656-
tps: ~[ty::t], tid: ast::def_id,
657-
f: val_and_ty_fn) -> block {
656+
tps: &[ty::t], f: val_and_ty_fn) -> block {
658657
let _icx = cx.insn_ctxt("iter_variant");
659-
if variant.args.len() == 0u { return cx; }
660-
let fn_ty = variant.ctor_ty;
661-
let ccx = cx.ccx();
658+
let tcx = cx.tcx();
662659
let mut cx = cx;
663-
match ty::get(fn_ty).sty {
664-
ty::ty_bare_fn(ref fn_ty) => {
665-
let mut j = 0u;
666-
let v_id = variant.id;
667-
for vec::each(fn_ty.sig.inputs) |a| {
668-
let llfldp_a = GEP_enum(cx, a_tup, tid, v_id,
669-
/*bad*/copy tps, j);
670-
// This assumes the self type is absent (it passes
671-
// None for the self_ty_opt arg of substs_tps).
672-
// I think that's ok since you can't have an enum
673-
// inside a trait.
674-
let ty_subst = ty::subst_tps(ccx.tcx, tps, None, a.ty);
675-
cx = f(cx, llfldp_a, ty_subst);
676-
j += 1u;
677-
}
678-
}
679-
_ => cx.tcx().sess.bug(fmt!("iter_variant: not a function type: \
680-
%s (variant name = %s)",
681-
cx.ty_to_str(fn_ty),
682-
*cx.sess().str_of(variant.name)))
660+
661+
for variant.args.eachi |i, &arg| {
662+
cx = f(cx, adt::trans_GEP(cx, repr, av, variant.disr_val, i),
663+
ty::subst_tps(tcx, tps, None, arg));
683664
}
684665
return cx;
685666
}
@@ -708,45 +689,49 @@ pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
708689
}
709690
}
710691
ty::ty_enum(tid, ref substs) => {
711-
let variants = ty::enum_variants(cx.tcx(), tid);
712-
let n_variants = (*variants).len();
713-
714-
// Cast the enums to types we can GEP into.
715-
if n_variants == 1u {
716-
return iter_variant(cx,
717-
av,
718-
variants[0],
719-
/*bad*/copy substs.tps,
720-
tid,
721-
f);
722-
}
692+
let ccx = cx.ccx();
723693

724-
let ccx = cx.ccx();
725-
let llenumty = T_opaque_enum_ptr(ccx);
726-
let av_enum = PointerCast(cx, av, llenumty);
727-
let lldiscrim_a_ptr = GEPi(cx, av_enum, [0u, 0u]);
728-
let llunion_a_ptr = GEPi(cx, av_enum, [0u, 1u]);
729-
let lldiscrim_a = Load(cx, lldiscrim_a_ptr);
730-
731-
// NB: we must hit the discriminant first so that structural
732-
// comparison know not to proceed when the discriminants differ.
733-
cx = f(cx, lldiscrim_a_ptr, ty::mk_int(cx.tcx()));
734-
let unr_cx = sub_block(cx, ~"enum-iter-unr");
735-
Unreachable(unr_cx);
736-
let llswitch = Switch(cx, lldiscrim_a, unr_cx.llbb, n_variants);
737-
let next_cx = sub_block(cx, ~"enum-iter-next");
738-
for vec::each(*variants) |variant| {
739-
let variant_cx =
740-
sub_block(cx,
741-
~"enum-iter-variant-" +
742-
int::to_str(variant.disr_val));
743-
AddCase(llswitch, C_int(ccx, variant.disr_val), variant_cx.llbb);
744-
let variant_cx =
745-
iter_variant(variant_cx, llunion_a_ptr, *variant,
746-
/*bad*/copy (*substs).tps, tid, f);
747-
Br(variant_cx, next_cx.llbb);
748-
}
749-
return next_cx;
694+
let repr = adt::represent_type(ccx, t);
695+
let variants = ty::enum_variants(ccx.tcx, tid);
696+
let n_variants = (*variants).len();
697+
698+
// NB: we must hit the discriminant first so that structural
699+
// comparison know not to proceed when the discriminants differ.
700+
701+
match adt::trans_switch(cx, &repr, av) {
702+
(_match::single, None) => {
703+
cx = iter_variant(cx, &repr, av, variants[0],
704+
substs.tps, f);
705+
}
706+
(_match::switch, Some(lldiscrim_a)) => {
707+
cx = f(cx, lldiscrim_a, ty::mk_int(cx.tcx()));
708+
let unr_cx = sub_block(cx, ~"enum-iter-unr");
709+
Unreachable(unr_cx);
710+
let llswitch = Switch(cx, lldiscrim_a, unr_cx.llbb,
711+
n_variants);
712+
let next_cx = sub_block(cx, ~"enum-iter-next");
713+
714+
for vec::each(*variants) |variant| {
715+
let variant_cx =
716+
sub_block(cx, ~"enum-iter-variant-" +
717+
int::to_str(variant.disr_val));
718+
let variant_cx =
719+
iter_variant(variant_cx, &repr, av, *variant,
720+
substs.tps, f);
721+
match adt::trans_case(cx, &repr, variant.disr_val) {
722+
_match::single_result(r) => {
723+
AddCase(llswitch, r.val, variant_cx.llbb)
724+
}
725+
_ => ccx.sess.unimpl(~"value from adt::trans_case \
726+
in iter_structural_ty")
727+
}
728+
Br(variant_cx, next_cx.llbb);
729+
}
730+
cx = next_cx;
731+
}
732+
_ => ccx.sess.unimpl(~"value from adt::trans_switch \
733+
in iter_structural_ty")
734+
}
750735
}
751736
_ => cx.sess().unimpl(~"type in iter_structural_ty")
752737
}

0 commit comments

Comments
 (0)