Skip to content

Commit 874e8e3

Browse files
committed
rustc: Have tag patterns use the type parameter information from the typechecker instead of trying to deduce it in trans. Un-XFAIL test/run-pass/generic-tag-values.rs.
1 parent bafcbb1 commit 874e8e3

File tree

3 files changed

+49
-11
lines changed

3 files changed

+49
-11
lines changed

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-values.rs \
457456
iter-range.rs \
458457
iter-ret.rs \
459458
lazychan.rs \

src/comp/middle/trans.rs

+46-8
Original file line numberDiff line numberDiff line change
@@ -1185,18 +1185,27 @@ fn GEP_tup_like(@block_ctxt cx, @ty.t t,
11851185
// This function uses GEP_tup_like() above and automatically performs casts as
11861186
// appropriate. @llblobptr is the data part of a tag value; its actual type is
11871187
// meaningless, as it will be cast away.
1188-
fn GEP_tag(@block_ctxt cx, ValueRef llblobptr, &ast.variant variant, int ix)
1188+
fn GEP_tag(@block_ctxt cx,
1189+
ValueRef llblobptr,
1190+
&ast.def_id tag_id,
1191+
&ast.def_id variant_id,
1192+
vec[@ty.t] ty_substs,
1193+
int ix)
11891194
-> result {
1195+
auto ty_params = tag_ty_params(cx.fcx.ccx, tag_id);
1196+
auto variant = tag_variant_with_id(cx.fcx.ccx, tag_id, variant_id);
1197+
11901198
// Synthesize a tuple type so that GEP_tup_like() can work its magic.
11911199
// Separately, store the type of the element we're interested in.
11921200
auto arg_tys = arg_tys_of_fn(variant.ann);
11931201
auto elem_ty = ty.plain_ty(ty.ty_nil); // typestate infelicity
11941202
auto i = 0;
11951203
let vec[@ty.t] true_arg_tys = vec();
11961204
for (ty.arg a in arg_tys) {
1197-
true_arg_tys += vec(a.ty);
1205+
auto arg_ty = ty.substitute_ty_params(ty_params, ty_substs, a.ty);
1206+
true_arg_tys += vec(arg_ty);
11981207
if (i == ix) {
1199-
elem_ty = a.ty;
1208+
elem_ty = arg_ty;
12001209
}
12011210

12021211
i += 1;
@@ -2283,6 +2292,24 @@ fn node_ann_type(@crate_ctxt cx, &ast.ann a) -> @ty.t {
22832292
}
22842293
}
22852294

2295+
fn node_ann_ty_params(&ast.ann a) -> vec[@ty.t] {
2296+
alt (a) {
2297+
case (ast.ann_none) {
2298+
log "missing type annotation";
2299+
fail;
2300+
}
2301+
case (ast.ann_type(_, ?tps_opt)) {
2302+
alt (tps_opt) {
2303+
case (none[vec[@ty.t]]) {
2304+
log "type annotation has no ty params";
2305+
fail;
2306+
}
2307+
case (some[vec[@ty.t]](?tps)) { ret tps; }
2308+
}
2309+
}
2310+
}
2311+
}
2312+
22862313
fn node_type(@crate_ctxt cx, &ast.ann a) -> TypeRef {
22872314
ret type_of(cx, node_ann_type(cx, a));
22882315
}
@@ -2981,13 +3008,15 @@ fn trans_pat_match(@block_ctxt cx, @ast.pat pat, ValueRef llval,
29813008
C_int(variant_tag));
29823009
cx.build.CondBr(lleq, matched_cx.llbb, next_cx.llbb);
29833010

3011+
auto ty_params = node_ann_ty_params(ann);
3012+
29843013
if (_vec.len[@ast.pat](subpats) > 0u) {
29853014
auto llblobptr = matched_cx.build.GEP(lltagptr,
29863015
vec(C_int(0), C_int(1)));
29873016
auto i = 0;
29883017
for (@ast.pat subpat in subpats) {
2989-
auto rslt = GEP_tag(matched_cx, llblobptr, variants.(i),
2990-
i);
3018+
auto rslt = GEP_tag(matched_cx, llblobptr, vdef._0,
3019+
vdef._1, ty_params, i);
29913020
auto llsubvalptr = rslt.val;
29923021
matched_cx = rslt.bcx;
29933022

@@ -3025,7 +3054,7 @@ fn trans_pat_binding(@block_ctxt cx, @ast.pat pat, ValueRef llval)
30253054

30263055
ret copy_ty(bcx, INIT, dst, llval, ty);
30273056
}
3028-
case (ast.pat_tag(_, ?subpats, ?vdef_opt, _)) {
3057+
case (ast.pat_tag(_, ?subpats, ?vdef_opt, ?ann)) {
30293058
if (_vec.len[@ast.pat](subpats) == 0u) { ret res(cx, llval); }
30303059

30313060
// Get the appropriate variant for this tag.
@@ -3036,10 +3065,13 @@ fn trans_pat_binding(@block_ctxt cx, @ast.pat pat, ValueRef llval)
30363065
T_opaque_tag_ptr(cx.fcx.ccx.tn));
30373066
auto llblobptr = cx.build.GEP(lltagptr, vec(C_int(0), C_int(1)));
30383067

3068+
auto ty_param_substs = node_ann_ty_params(ann);
3069+
30393070
auto this_cx = cx;
30403071
auto i = 0;
30413072
for (@ast.pat subpat in subpats) {
3042-
auto rslt = GEP_tag(this_cx, llblobptr, variant, i);
3073+
auto rslt = GEP_tag(this_cx, llblobptr, vdef._0, vdef._1,
3074+
ty_param_substs, i);
30433075
this_cx = rslt.bcx;
30443076
auto llsubvalptr = rslt.val;
30453077

@@ -4926,6 +4958,11 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
49264958
none[TypeRef], ret_ty_of_fn(variant.ann),
49274959
fn_args, ty_params);
49284960

4961+
let vec[@ty.t] ty_param_substs = vec();
4962+
for (ast.ty_param tp in ty_params) {
4963+
ty_param_substs += vec(plain_ty(ty.ty_param(tp.id)));
4964+
}
4965+
49294966
auto bcx = new_top_block_ctxt(fcx);
49304967

49314968
auto arg_tys = arg_tys_of_fn(variant.ann);
@@ -4944,7 +4981,8 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
49444981

49454982
i = 0u;
49464983
for (ast.variant_arg va in variant.args) {
4947-
auto rslt = GEP_tag(bcx, llblobptr, variant, i as int);
4984+
auto rslt = GEP_tag(bcx, llblobptr, tag_id, variant.id,
4985+
ty_param_substs, i as int);
49484986
bcx = rslt.bcx;
49494987
auto lldestptr = rslt.val;
49504988

src/comp/middle/typeck.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,7 @@ fn demand_pat(&@fn_ctxt fcx, @ty.t expected, @ast.pat pat) -> @ast.pat {
10851085
fail;
10861086
}
10871087
}
1088+
auto tps_opt = some[vec[@ty.t]](ty_param_substs);
10881089

10891090
// The type of the tag isn't enough; we also have to get the type
10901091
// of the variant, which is either a tag type in the case of
@@ -1100,7 +1101,7 @@ fn demand_pat(&@fn_ctxt fcx, @ty.t expected, @ast.pat pat) -> @ast.pat {
11001101
// Nullary tag variant.
11011102
check (subpats_len == 0u);
11021103
p_1 = ast.pat_tag(id, subpats, vdef_opt,
1103-
ast.ann_type(t, none[vec[@ty.t]]));
1104+
ast.ann_type(t, tps_opt));
11041105
}
11051106
case (ty.ty_fn(_, ?args, ?tag_ty)) {
11061107
// N-ary tag variant.
@@ -1115,7 +1116,7 @@ fn demand_pat(&@fn_ctxt fcx, @ty.t expected, @ast.pat pat) -> @ast.pat {
11151116
i += 1u;
11161117
}
11171118
p_1 = ast.pat_tag(id, new_subpats, vdef_opt,
1118-
ast.ann_type(tag_ty, none[vec[@ty.t]]));
1119+
ast.ann_type(tag_ty, tps_opt));
11191120
}
11201121
}
11211122
}

0 commit comments

Comments
 (0)