Skip to content

Commit 1377acd

Browse files
committed
---
yaml --- r: 1399 b: refs/heads/master c: 10befcd h: refs/heads/master i: 1397: ac30d48 1395: 87cdff9 1391: e20878d v: v3
1 parent 3f4e33b commit 1377acd

File tree

5 files changed

+100
-35
lines changed

5 files changed

+100
-35
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: 79d3ceaac0b4a6ca83f0ff7b8b533649fc5165a1
2+
refs/heads/master: 10befcd9a4d9f68e2dbec84c4a86450a021143fb

trunk/src/comp/middle/trans.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t) -> TypeRef {
490490
}
491491
case (ty.ty_char) { ret T_char(); }
492492
case (ty.ty_str) { ret T_ptr(T_str()); }
493-
case (ty.ty_tag(?tag_id)) {
493+
case (ty.ty_tag(?tag_id, _)) {
494494
ret llvm.LLVMResolveTypeHandle(cx.tags.get(tag_id).th.llth);
495495
}
496496
case (ty.ty_box(?t)) {
@@ -1445,7 +1445,9 @@ fn iter_structural_ty(@block_ctxt cx,
14451445
i += 1;
14461446
}
14471447
}
1448-
case (ty.ty_tag(?tid)) {
1448+
case (ty.ty_tag(?tid, _)) {
1449+
// TODO: type params!
1450+
14491451
check (cx.fcx.ccx.tags.contains_key(tid));
14501452
auto info = cx.fcx.ccx.tags.get(tid);
14511453
auto n_variants = _vec.len[tup(ast.def_id,arity)](info.variants);

trunk/src/comp/middle/ty.rs

Lines changed: 66 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ tag sty {
3232
ty_machine(util.common.ty_mach);
3333
ty_char;
3434
ty_str;
35-
ty_tag(ast.def_id);
35+
ty_tag(ast.def_id, vec[@t]);
3636
ty_box(@t);
3737
ty_vec(@t);
3838
ty_tup(vec[@t]);
@@ -42,7 +42,7 @@ tag sty {
4242
ty_obj(vec[method]);
4343
ty_var(int); // ephemeral type var
4444
ty_local(ast.def_id); // type of a local var
45-
ty_param(ast.def_id); // fn type param
45+
ty_param(ast.def_id); // fn/tag type param
4646
ty_type;
4747
ty_native;
4848
// TODO: ty_fn_arg(@t), for a possibly-aliased function argument
@@ -235,9 +235,14 @@ fn ty_to_str(&@t typ) -> str {
235235
s = "rec(" + _str.connect(strs, ",") + ")";
236236
}
237237

238-
case (ty_tag(_)) {
238+
case (ty_tag(_, ?tps)) {
239239
// The user should never see this if the cname is set properly!
240240
s = "<tag>";
241+
if (_vec.len[@t](tps) > 0u) {
242+
auto f = ty_to_str;
243+
auto strs = _vec.map[@t,str](f, tps);
244+
s += "[" + _str.connect(strs, ",") + "]";
245+
}
241246
}
242247

243248
case (ty_fn(?inputs, ?output)) {
@@ -291,7 +296,6 @@ fn fold_ty(ty_fold fld, @t ty) -> @t {
291296
case (ty_machine(_)) { ret fld.fold_simple_ty(ty); }
292297
case (ty_char) { ret fld.fold_simple_ty(ty); }
293298
case (ty_str) { ret fld.fold_simple_ty(ty); }
294-
case (ty_tag(_)) { ret fld.fold_simple_ty(ty); }
295299
case (ty_type) { ret fld.fold_simple_ty(ty); }
296300
case (ty_native) { ret fld.fold_simple_ty(ty); }
297301
case (ty_box(?subty)) {
@@ -300,6 +304,13 @@ fn fold_ty(ty_fold fld, @t ty) -> @t {
300304
case (ty_vec(?subty)) {
301305
ret rewrap(ty, ty_vec(fold_ty(fld, subty)));
302306
}
307+
case (ty_tag(?tid, ?subtys)) {
308+
let vec[@t] new_subtys = vec();
309+
for (@t subty in subtys) {
310+
new_subtys += vec(fold_ty(fld, subty));
311+
}
312+
ret rewrap(ty, ty_tag(tid, new_subtys));
313+
}
303314
case (ty_tup(?subtys)) {
304315
let vec[@t] new_subtys = vec();
305316
for (@t subty in subtys) {
@@ -364,23 +375,23 @@ fn type_is_nil(@t ty) -> bool {
364375

365376
fn type_is_structural(@t ty) -> bool {
366377
alt (ty.struct) {
367-
case (ty_tup(_)) { ret true; }
368-
case (ty_rec(_)) { ret true; }
369-
case (ty_tag(_)) { ret true; }
370-
case (ty_fn(_,_)) { ret true; }
371-
case (ty_obj(_)) { ret true; }
372-
case (_) { ret false; }
378+
case (ty_tup(_)) { ret true; }
379+
case (ty_rec(_)) { ret true; }
380+
case (ty_tag(_,_)) { ret true; }
381+
case (ty_fn(_,_)) { ret true; }
382+
case (ty_obj(_)) { ret true; }
383+
case (_) { ret false; }
373384
}
374385
fail;
375386
}
376387

377388
fn type_is_tup_like(@t ty) -> bool {
378389
alt (ty.struct) {
379-
case (ty_box(_)) { ret true; }
380-
case (ty_tup(_)) { ret true; }
381-
case (ty_rec(_)) { ret true; }
382-
case (ty_tag(_)) { ret true; }
383-
case (_) { ret false; }
390+
case (ty_box(_)) { ret true; }
391+
case (ty_tup(_)) { ret true; }
392+
case (ty_rec(_)) { ret true; }
393+
case (ty_tag(_,_)) { ret true; }
394+
case (_) { ret false; }
384395
}
385396
fail;
386397
}
@@ -641,8 +652,13 @@ fn item_ty(@ast.item it) -> ty_params_and_ty {
641652
result_ty = ann_to_type(ann);
642653
}
643654
case (ast.item_tag(_, _, ?tps, ?did)) {
655+
// Create a new generic polytype.
644656
ty_params = tps;
645-
result_ty = plain_ty(ty_tag(did));
657+
let vec[@t] subtys = vec();
658+
for (ast.ty_param tp in tps) {
659+
subtys += vec(plain_ty(ty_param(tp.id)));
660+
}
661+
result_ty = plain_ty(ty_tag(did, subtys));
646662
}
647663
case (ast.item_obj(_, _, ?tps, _, ?ann)) {
648664
ty_params = tps;
@@ -1001,13 +1017,42 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
10011017
case (ty.ty_type) { ret struct_cmp(expected, actual); }
10021018
case (ty.ty_native) { ret struct_cmp(expected, actual); }
10031019

1004-
case (ty.ty_tag(?expected_id)) {
1020+
case (ty.ty_tag(?expected_id, ?expected_tps)) {
10051021
alt (actual.struct) {
1006-
case (ty.ty_tag(?actual_id)) {
1007-
if (expected_id._0 == actual_id._0 &&
1008-
expected_id._1 == actual_id._1) {
1009-
ret ures_ok(expected);
1022+
case (ty.ty_tag(?actual_id, ?actual_tps)) {
1023+
if (expected_id._0 != actual_id._0 ||
1024+
expected_id._1 != actual_id._1) {
1025+
ret ures_err(terr_mismatch, expected, actual);
1026+
}
1027+
1028+
// TODO: factor this cruft out, see the TODO in the
1029+
// ty.ty_tup case
1030+
let vec[@ty.t] result_tps = vec();
1031+
auto i = 0u;
1032+
auto expected_len = _vec.len[@ty.t](expected_tps);
1033+
while (i < expected_len) {
1034+
auto expected_tp = expected_tps.(i);
1035+
auto actual_tp = actual_tps.(i);
1036+
1037+
auto result = unify_step(bindings,
1038+
expected_tp,
1039+
actual_tp,
1040+
handler);
1041+
1042+
alt (result) {
1043+
case (ures_ok(?rty)) {
1044+
append[@ty.t](result_tps, rty);
1045+
}
1046+
case (_) {
1047+
ret result;
1048+
}
1049+
}
1050+
1051+
i += 1u;
10101052
}
1053+
1054+
ret ures_ok(plain_ty(ty.ty_tag(expected_id,
1055+
result_tps)));
10111056
}
10121057
case (_) { /* fall through */ }
10131058
}

trunk/src/comp/middle/typeck.rs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -430,8 +430,13 @@ fn collect_item_types(session.session sess, @ast.crate crate)
430430
ret ty_;
431431
}
432432

433-
case (ast.item_tag(_, _, _, ?def_id)) {
434-
auto t = plain_ty(ty.ty_tag(def_id));
433+
case (ast.item_tag(_, _, ?tps, ?def_id)) {
434+
// Create a new generic polytype.
435+
let vec[@ty.t] subtys = vec();
436+
for (ast.ty_param tp in tps) {
437+
subtys += vec(plain_ty(ty.ty_param(tp.id)));
438+
}
439+
auto t = plain_ty(ty.ty_tag(def_id, subtys));
435440
item_to_ty.insert(def_id, t);
436441
ret t;
437442
}
@@ -468,15 +473,23 @@ fn collect_item_types(session.session sess, @ast.crate crate)
468473
fn get_tag_variant_types(@ty_item_table id_to_ty_item,
469474
@ty_table item_to_ty,
470475
&ast.def_id tag_id,
471-
&vec[ast.variant] variants) -> vec[ast.variant] {
476+
&vec[ast.variant] variants,
477+
&vec[ast.ty_param] ty_params)
478+
-> vec[ast.variant] {
472479
let vec[ast.variant] result = vec();
473480

481+
// Create a set of parameter types shared among all the variants.
482+
let vec[@ty.t] ty_param_tys = vec();
483+
for (ast.ty_param tp in ty_params) {
484+
ty_param_tys += vec(plain_ty(ty.ty_param(tp.id)));
485+
}
486+
474487
for (ast.variant variant in variants) {
475-
// Nullary tag constructors get truned into constants; n-ary tag
488+
// Nullary tag constructors get turned into constants; n-ary tag
476489
// constructors get turned into functions.
477490
auto result_ty;
478491
if (_vec.len[ast.variant_arg](variant.args) == 0u) {
479-
result_ty = plain_ty(ty.ty_tag(tag_id));
492+
result_ty = plain_ty(ty.ty_tag(tag_id, ty_param_tys));
480493
} else {
481494
// As above, tell ast_ty_to_ty() that trans_ty_item_to_ty()
482495
// should be called to resolve named types.
@@ -487,7 +500,7 @@ fn collect_item_types(session.session sess, @ast.crate crate)
487500
auto arg_ty = ast_ty_to_ty(f, va.ty);
488501
args += vec(rec(mode=ast.alias, ty=arg_ty));
489502
}
490-
auto tag_t = plain_ty(ty.ty_tag(tag_id));
503+
auto tag_t = plain_ty(ty.ty_tag(tag_id, ty_param_tys));
491504
result_ty = plain_ty(ty.ty_fn(args, tag_t));
492505
}
493506

@@ -674,7 +687,9 @@ fn collect_item_types(session.session sess, @ast.crate crate)
674687
ast.def_id id) -> @ast.item {
675688
auto variants_t = get_tag_variant_types(e.id_to_ty_item,
676689
e.item_to_ty,
677-
id, variants);
690+
id,
691+
variants,
692+
ty_params);
678693
auto item = ast.item_tag(i, variants_t, ty_params, id);
679694
ret @fold.respan[ast.item_](sp, item);
680695
}
@@ -857,7 +872,7 @@ fn demand_pat(&@fn_ctxt fcx, @ty.t expected, @ast.pat pat) -> @ast.pat {
857872

858873
auto subpats_len = _vec.len[@ast.pat](subpats);
859874
alt (variant_ty.struct) {
860-
case (ty.ty_tag(_)) {
875+
case (ty.ty_tag(_, _)) {
861876
// Nullary tag variant.
862877
check (subpats_len == 0u);
863878
p_1 = ast.pat_tag(id, subpats, vdef_opt, ast.ann_type(t));
@@ -1198,7 +1213,9 @@ fn check_pat(&@fn_ctxt fcx, @ast.pat pat) -> @ast.pat {
11981213
}
11991214

12001215
// Nullary variants have tag types.
1201-
case (ty.ty_tag(?tid)) {
1216+
case (ty.ty_tag(?tid, _)) {
1217+
// TODO: ty params
1218+
12021219
auto subpats_len = _vec.len[@ast.pat](subpats);
12031220
if (subpats_len > 0u) {
12041221
// TODO: pluralize properly
@@ -1212,7 +1229,8 @@ fn check_pat(&@fn_ctxt fcx, @ast.pat pat) -> @ast.pat {
12121229
fail; // TODO: recover
12131230
}
12141231

1215-
auto ann = ast.ann_type(plain_ty(ty.ty_tag(tid)));
1232+
let vec[@ty.t] tys = vec(); // FIXME
1233+
auto ann = ast.ann_type(plain_ty(ty.ty_tag(tid, tys)));
12161234
new_pat = ast.pat_tag(p, subpats, vdef_opt, ann);
12171235
}
12181236
}

trunk/src/test/run-pass/generic-tag.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ tag option[T] {
66
fn main() {
77
let option[int] a = some[int](@10);
88
a = none[int];
9-
}
9+
}

0 commit comments

Comments
 (0)