aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPatrick Walton <[email protected]>2011-03-09 17:48:07 -0800
committerPatrick Walton <[email protected]>2011-03-09 17:50:46 -0800
commit874e8e35055aff1bb7cb5b8afd9e1c27c8cf20de (patch)
tree2e8c199daebdfa86e9299e8a9bcc815e02dcce80 /src
parentFold exports. (diff)
downloadrust-874e8e35055aff1bb7cb5b8afd9e1c27c8cf20de.tar.xz
rust-874e8e35055aff1bb7cb5b8afd9e1c27c8cf20de.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile1
-rw-r--r--src/comp/middle/trans.rs54
-rw-r--r--src/comp/middle/typeck.rs5
3 files changed, 49 insertions, 11 deletions
diff --git a/src/Makefile b/src/Makefile
index 2c35d07f..70e2330e 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -453,7 +453,6 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \
foreach-put-structured.rs \
foreach-simple-outer-slot.rs \
generic-iter-frame.rs \
- generic-tag-values.rs \
iter-range.rs \
iter-ret.rs \
lazychan.rs \
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 3c5253ff..00e7e6d8 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -1185,8 +1185,16 @@ fn GEP_tup_like(@block_ctxt cx, @ty.t t,
// This function uses GEP_tup_like() above and automatically performs casts as
// appropriate. @llblobptr is the data part of a tag value; its actual type is
// meaningless, as it will be cast away.
-fn GEP_tag(@block_ctxt cx, ValueRef llblobptr, &ast.variant variant, int ix)
+fn GEP_tag(@block_ctxt cx,
+ ValueRef llblobptr,
+ &ast.def_id tag_id,
+ &ast.def_id variant_id,
+ vec[@ty.t] ty_substs,
+ int ix)
-> result {
+ auto ty_params = tag_ty_params(cx.fcx.ccx, tag_id);
+ auto variant = tag_variant_with_id(cx.fcx.ccx, tag_id, variant_id);
+
// Synthesize a tuple type so that GEP_tup_like() can work its magic.
// Separately, store the type of the element we're interested in.
auto arg_tys = arg_tys_of_fn(variant.ann);
@@ -1194,9 +1202,10 @@ fn GEP_tag(@block_ctxt cx, ValueRef llblobptr, &ast.variant variant, int ix)
auto i = 0;
let vec[@ty.t] true_arg_tys = vec();
for (ty.arg a in arg_tys) {
- true_arg_tys += vec(a.ty);
+ auto arg_ty = ty.substitute_ty_params(ty_params, ty_substs, a.ty);
+ true_arg_tys += vec(arg_ty);
if (i == ix) {
- elem_ty = a.ty;
+ elem_ty = arg_ty;
}
i += 1;
@@ -2283,6 +2292,24 @@ fn node_ann_type(@crate_ctxt cx, &ast.ann a) -> @ty.t {
}
}
+fn node_ann_ty_params(&ast.ann a) -> vec[@ty.t] {
+ alt (a) {
+ case (ast.ann_none) {
+ log "missing type annotation";
+ fail;
+ }
+ case (ast.ann_type(_, ?tps_opt)) {
+ alt (tps_opt) {
+ case (none[vec[@ty.t]]) {
+ log "type annotation has no ty params";
+ fail;
+ }
+ case (some[vec[@ty.t]](?tps)) { ret tps; }
+ }
+ }
+ }
+}
+
fn node_type(@crate_ctxt cx, &ast.ann a) -> TypeRef {
ret type_of(cx, node_ann_type(cx, a));
}
@@ -2981,13 +3008,15 @@ fn trans_pat_match(@block_ctxt cx, @ast.pat pat, ValueRef llval,
C_int(variant_tag));
cx.build.CondBr(lleq, matched_cx.llbb, next_cx.llbb);
+ auto ty_params = node_ann_ty_params(ann);
+
if (_vec.len[@ast.pat](subpats) > 0u) {
auto llblobptr = matched_cx.build.GEP(lltagptr,
vec(C_int(0), C_int(1)));
auto i = 0;
for (@ast.pat subpat in subpats) {
- auto rslt = GEP_tag(matched_cx, llblobptr, variants.(i),
- i);
+ auto rslt = GEP_tag(matched_cx, llblobptr, vdef._0,
+ vdef._1, ty_params, i);
auto llsubvalptr = rslt.val;
matched_cx = rslt.bcx;
@@ -3025,7 +3054,7 @@ fn trans_pat_binding(@block_ctxt cx, @ast.pat pat, ValueRef llval)
ret copy_ty(bcx, INIT, dst, llval, ty);
}
- case (ast.pat_tag(_, ?subpats, ?vdef_opt, _)) {
+ case (ast.pat_tag(_, ?subpats, ?vdef_opt, ?ann)) {
if (_vec.len[@ast.pat](subpats) == 0u) { ret res(cx, llval); }
// Get the appropriate variant for this tag.
@@ -3036,10 +3065,13 @@ fn trans_pat_binding(@block_ctxt cx, @ast.pat pat, ValueRef llval)
T_opaque_tag_ptr(cx.fcx.ccx.tn));
auto llblobptr = cx.build.GEP(lltagptr, vec(C_int(0), C_int(1)));
+ auto ty_param_substs = node_ann_ty_params(ann);
+
auto this_cx = cx;
auto i = 0;
for (@ast.pat subpat in subpats) {
- auto rslt = GEP_tag(this_cx, llblobptr, variant, i);
+ auto rslt = GEP_tag(this_cx, llblobptr, vdef._0, vdef._1,
+ ty_param_substs, i);
this_cx = rslt.bcx;
auto llsubvalptr = rslt.val;
@@ -4926,6 +4958,11 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
none[TypeRef], ret_ty_of_fn(variant.ann),
fn_args, ty_params);
+ let vec[@ty.t] ty_param_substs = vec();
+ for (ast.ty_param tp in ty_params) {
+ ty_param_substs += vec(plain_ty(ty.ty_param(tp.id)));
+ }
+
auto bcx = new_top_block_ctxt(fcx);
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,
i = 0u;
for (ast.variant_arg va in variant.args) {
- auto rslt = GEP_tag(bcx, llblobptr, variant, i as int);
+ auto rslt = GEP_tag(bcx, llblobptr, tag_id, variant.id,
+ ty_param_substs, i as int);
bcx = rslt.bcx;
auto lldestptr = rslt.val;
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index a0adf55a..7dfe918c 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -1085,6 +1085,7 @@ fn demand_pat(&@fn_ctxt fcx, @ty.t expected, @ast.pat pat) -> @ast.pat {
fail;
}
}
+ auto tps_opt = some[vec[@ty.t]](ty_param_substs);
// The type of the tag isn't enough; we also have to get the type
// 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 {
// Nullary tag variant.
check (subpats_len == 0u);
p_1 = ast.pat_tag(id, subpats, vdef_opt,
- ast.ann_type(t, none[vec[@ty.t]]));
+ ast.ann_type(t, tps_opt));
}
case (ty.ty_fn(_, ?args, ?tag_ty)) {
// N-ary tag variant.
@@ -1115,7 +1116,7 @@ fn demand_pat(&@fn_ctxt fcx, @ty.t expected, @ast.pat pat) -> @ast.pat {
i += 1u;
}
p_1 = ast.pat_tag(id, new_subpats, vdef_opt,
- ast.ann_type(tag_ty, none[vec[@ty.t]]));
+ ast.ann_type(tag_ty, tps_opt));
}
}
}