Skip to content

Commit f7d1004

Browse files
committed
---
yaml --- r: 1438 b: refs/heads/master c: 7a1d01e h: refs/heads/master v: v3
1 parent b52e014 commit f7d1004

File tree

3 files changed

+69
-7
lines changed

3 files changed

+69
-7
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 081c3aa76dd0805767e0233c0cc6ccf313cf44ba
2+
refs/heads/master: 7a1d01effcfa5763bc62aefba40f67ad2130d28d

trunk/src/comp/middle/typeck.rs

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -919,9 +919,42 @@ fn demand_pat(&@fn_ctxt fcx, @ty.t expected, @ast.pat pat) -> @ast.pat {
919919
// acquire here with the type parameters provided to us by
920920
// "expected".
921921

922+
// Grab the values for the type parameters of the tag from the
923+
// expected type.
924+
let vec[@ty.t] typaram_bindings = vec(); // FIXME: typestate botch
925+
alt (expected.struct) {
926+
case (ty.ty_tag(_, ?tps)) { typaram_bindings = tps; }
927+
case (_) {
928+
log "tag pattern didn't have tag type?!";
929+
fail;
930+
}
931+
}
932+
933+
// Get the item corresponding to the tag and its type.
922934
auto vdef = option.get[ast.variant_def](vdef_opt);
923935
auto variant_ty = fcx.ccx.item_types.get(vdef._1);
924936

937+
// FIXME: typestate botch
938+
let option.t[@ast.item] item_opt = none[@ast.item];
939+
alt (fcx.ccx.item_items.get(vdef._0)) {
940+
case (any_item_rust(?it)) { item_opt = some[@ast.item](it); }
941+
case (_) {
942+
log "tag item isn't a Rust item?!";
943+
fail;
944+
}
945+
}
946+
let @ast.item item = option.get[@ast.item](item_opt);
947+
948+
// Get the IDs of the type parameters from that item.
949+
let vec[ast.ty_param] ty_params = vec(); // FIXME: typestate botch
950+
alt (item.node) {
951+
case (ast.item_tag(_, _, ?tps, _)) { ty_params = tps; }
952+
case (_) {
953+
log "tag's corresponding item isn't a tag?!";
954+
fail;
955+
}
956+
}
957+
925958
auto subpats_len = _vec.len[@ast.pat](subpats);
926959
alt (variant_ty.struct) {
927960
case (ty.ty_tag(_, _)) {
@@ -930,10 +963,14 @@ fn demand_pat(&@fn_ctxt fcx, @ty.t expected, @ast.pat pat) -> @ast.pat {
930963
p_1 = ast.pat_tag(id, subpats, vdef_opt, ast.ann_type(t));
931964
}
932965
case (ty.ty_fn(_, ?args, ?tag_ty)) {
966+
// N-ary tag variant.
933967
let vec[@ast.pat] new_subpats = vec();
934968
auto i = 0u;
935969
for (arg a in args) {
936-
auto new_subpat = demand_pat(fcx, a.ty, subpats.(i));
970+
auto arg_ty = ty.substitute_ty_params(ty_params,
971+
typaram_bindings, a.ty);
972+
auto new_subpat = demand_pat(fcx, arg_ty,
973+
subpats.(i));
937974
new_subpats += vec(new_subpat);
938975
i += 1u;
939976
}
@@ -1260,14 +1297,13 @@ fn check_pat(&@fn_ctxt fcx, @ast.pat pat) -> @ast.pat {
12601297
new_subpats += vec(check_pat(fcx, subpat));
12611298
}
12621299

1263-
auto ann = ast.ann_type(tag_ty);
1300+
auto tag_ty_g = generalize_ty(fcx.ccx, tag_ty);
1301+
auto ann = ast.ann_type(tag_ty_g);
12641302
new_pat = ast.pat_tag(p, new_subpats, vdef_opt, ann);
12651303
}
12661304

12671305
// Nullary variants have tag types.
1268-
case (ty.ty_tag(?tid, _)) {
1269-
// TODO: ty params
1270-
1306+
case (ty.ty_tag(?tid, ?tps)) {
12711307
auto subpats_len = _vec.len[@ast.pat](subpats);
12721308
if (subpats_len > 0u) {
12731309
// TODO: pluralize properly
@@ -1281,7 +1317,14 @@ fn check_pat(&@fn_ctxt fcx, @ast.pat pat) -> @ast.pat {
12811317
fail; // TODO: recover
12821318
}
12831319

1284-
let vec[@ty.t] tys = vec(); // FIXME
1320+
// Add the appropriate number of type variables.
1321+
let vec[@ty.t] tys = vec();
1322+
auto i = 0u;
1323+
while (i < _vec.len[@ty.t](tps)) {
1324+
tys += vec(next_ty_var(fcx.ccx));
1325+
i += 1u;
1326+
}
1327+
12851328
auto ann = ast.ann_type(plain_ty(ty.ty_tag(tid, tys)));
12861329
new_pat = ast.pat_tag(p, subpats, vdef_opt, ann);
12871330
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
tag foo[T] {
2+
arm(@T);
3+
}
4+
5+
fn altfoo[T](foo[T] f) {
6+
auto hit = false;
7+
alt (f) {
8+
case (arm[T](?x)) {
9+
log "in arm";
10+
hit = true;
11+
}
12+
}
13+
check (hit);
14+
}
15+
16+
fn main() {
17+
altfoo[int](arm[int](@10));
18+
}
19+

0 commit comments

Comments
 (0)