Skip to content

Commit 2a81baf

Browse files
committed
---
yaml --- r: 1579 b: refs/heads/master c: 7dc64b4 h: refs/heads/master i: 1577: f5b0014 1575: bd2a70b v: v3
1 parent 0197237 commit 2a81baf

File tree

3 files changed

+51
-34
lines changed

3 files changed

+51
-34
lines changed

[refs]

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: ba2e04f271ca4015a3fb22dd01543ab9dc5d6543
2+
refs/heads/master: 7dc64b45b5149a566ad6d1284f8f90eb10468ca3

trunk/src/Makefile

-1
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,6 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \
453453
foreach-put-structured.rs \
454454
foreach-simple-outer-slot.rs \
455455
generic-iter-frame.rs \
456-
generic-tag-alt.rs \
457456
generic-tag-values.rs \
458457
iter-range.rs \
459458
iter-ret.rs \

trunk/src/comp/middle/trans.rs

+50-32
Original file line numberDiff line numberDiff line change
@@ -1730,6 +1730,25 @@ fn tag_variants(@crate_ctxt cx, ast.def_id id) -> vec[ast.variant] {
17301730
fail; // not reached
17311731
}
17321732

1733+
// Returns the tag variant with the given ID.
1734+
fn tag_variant_with_id(@crate_ctxt cx,
1735+
&ast.def_id tag_id,
1736+
&ast.def_id variant_id) -> ast.variant {
1737+
auto variants = tag_variants(cx, tag_id);
1738+
1739+
auto i = 0u;
1740+
while (i < _vec.len[ast.variant](variants)) {
1741+
auto variant = variants.(i);
1742+
if (common.def_eq(variant.id, variant_id)) {
1743+
ret variant;
1744+
}
1745+
i += 1u;
1746+
}
1747+
1748+
log "tag_variant_with_id(): no variant exists with that ID";
1749+
fail;
1750+
}
1751+
17331752
// Returns a new plain tag type of the given ID with no type parameters. Don't
17341753
// use this function in new code; it's a hack to keep things working for now.
17351754
fn mk_plain_tag(ast.def_id tid) -> @ty.t {
@@ -2909,23 +2928,6 @@ fn trans_do_while(@block_ctxt cx, &ast.block body,
29092928

29102929
// Pattern matching translation
29112930

2912-
// Returns a pointer to the union part of the LLVM representation of a tag
2913-
// type, cast to the appropriate type.
2914-
fn get_pat_union_ptr(@block_ctxt cx, vec[@ast.pat] subpats, ValueRef llval)
2915-
-> ValueRef {
2916-
auto llblobptr = cx.build.GEP(llval, vec(C_int(0), C_int(1)));
2917-
2918-
// Generate the union type.
2919-
let vec[TypeRef] llsubpattys = vec();
2920-
for (@ast.pat subpat in subpats) {
2921-
llsubpattys += vec(type_of(cx.fcx.ccx, pat_ty(subpat)));
2922-
}
2923-
2924-
// Recursively check subpatterns.
2925-
auto llunionty = T_struct(llsubpattys);
2926-
ret cx.build.TruncOrBitCast(llblobptr, T_ptr(llunionty));
2927-
}
2928-
29292931
fn trans_pat_match(@block_ctxt cx, @ast.pat pat, ValueRef llval,
29302932
@block_ctxt next_cx) -> result {
29312933
alt (pat.node) {
@@ -2943,7 +2945,11 @@ fn trans_pat_match(@block_ctxt cx, @ast.pat pat, ValueRef llval,
29432945
}
29442946

29452947
case (ast.pat_tag(?id, ?subpats, ?vdef_opt, ?ann)) {
2946-
auto lldiscrimptr = cx.build.GEP(llval, vec(C_int(0), C_int(0)));
2948+
auto lltagptr = cx.build.PointerCast(llval,
2949+
T_opaque_tag_ptr(cx.fcx.ccx.tn));
2950+
2951+
auto lldiscrimptr = cx.build.GEP(lltagptr,
2952+
vec(C_int(0), C_int(0)));
29472953
auto lldiscrim = cx.build.Load(lldiscrimptr);
29482954

29492955
auto vdef = option.get[ast.variant_def](vdef_opt);
@@ -2968,13 +2974,15 @@ fn trans_pat_match(@block_ctxt cx, @ast.pat pat, ValueRef llval,
29682974
cx.build.CondBr(lleq, matched_cx.llbb, next_cx.llbb);
29692975

29702976
if (_vec.len[@ast.pat](subpats) > 0u) {
2971-
auto llunionptr = get_pat_union_ptr(matched_cx, subpats,
2972-
llval);
2977+
auto llblobptr = matched_cx.build.GEP(lltagptr,
2978+
vec(C_int(0), C_int(1)));
29732979
auto i = 0;
29742980
for (@ast.pat subpat in subpats) {
2975-
auto llsubvalptr = matched_cx.build.GEP(llunionptr,
2976-
vec(C_int(0),
2977-
C_int(i)));
2981+
auto rslt = GEP_tag(matched_cx, llblobptr, variants.(i),
2982+
i);
2983+
auto llsubvalptr = rslt.val;
2984+
matched_cx = rslt.bcx;
2985+
29782986
auto llsubval = load_scalar_or_boxed(matched_cx,
29792987
llsubvalptr,
29802988
pat_ty(subpat));
@@ -2998,25 +3006,35 @@ fn trans_pat_binding(@block_ctxt cx, @ast.pat pat, ValueRef llval)
29983006
case (ast.pat_lit(_, _)) { ret res(cx, llval); }
29993007
case (ast.pat_bind(?id, ?def_id, ?ann)) {
30003008
auto ty = node_ann_type(cx.fcx.ccx, ann);
3001-
auto llty = type_of(cx.fcx.ccx, ty);
30023009

3003-
auto dst = cx.build.Alloca(llty);
3010+
auto rslt = alloc_ty(cx, ty);
3011+
auto dst = rslt.val;
3012+
auto bcx = rslt.bcx;
3013+
30043014
llvm.LLVMSetValueName(dst, _str.buf(id));
3005-
cx.fcx.lllocals.insert(def_id, dst);
3006-
cx.cleanups += clean(bind drop_slot(_, dst, ty));
3015+
bcx.fcx.lllocals.insert(def_id, dst);
3016+
bcx.cleanups += clean(bind drop_slot(_, dst, ty));
30073017

3008-
ret copy_ty(cx, INIT, dst, llval, ty);
3018+
ret copy_ty(bcx, INIT, dst, llval, ty);
30093019
}
3010-
case (ast.pat_tag(_, ?subpats, _, _)) {
3020+
case (ast.pat_tag(_, ?subpats, ?vdef_opt, _)) {
30113021
if (_vec.len[@ast.pat](subpats) == 0u) { ret res(cx, llval); }
30123022

3013-
auto llunionptr = get_pat_union_ptr(cx, subpats, llval);
3023+
// Get the appropriate variant for this tag.
3024+
auto vdef = option.get[ast.variant_def](vdef_opt);
3025+
auto variant = tag_variant_with_id(cx.fcx.ccx, vdef._0, vdef._1);
3026+
3027+
auto lltagptr = cx.build.PointerCast(llval,
3028+
T_opaque_tag_ptr(cx.fcx.ccx.tn));
3029+
auto llblobptr = cx.build.GEP(lltagptr, vec(C_int(0), C_int(1)));
30143030

30153031
auto this_cx = cx;
30163032
auto i = 0;
30173033
for (@ast.pat subpat in subpats) {
3018-
auto llsubvalptr = this_cx.build.GEP(llunionptr,
3019-
vec(C_int(0), C_int(i)));
3034+
auto rslt = GEP_tag(this_cx, llblobptr, variant, i);
3035+
this_cx = rslt.bcx;
3036+
auto llsubvalptr = rslt.val;
3037+
30203038
auto llsubval = load_scalar_or_boxed(this_cx, llsubvalptr,
30213039
pat_ty(subpat));
30223040
auto subpat_res = trans_pat_binding(this_cx, subpat,

0 commit comments

Comments
 (0)