Add type parameters to tag types
This commit is contained in:
parent
79d3ceaac0
commit
10befcd9a4
4 changed files with 99 additions and 34 deletions
|
|
@ -490,7 +490,7 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t) -> TypeRef {
|
|||
}
|
||||
case (ty.ty_char) { ret T_char(); }
|
||||
case (ty.ty_str) { ret T_ptr(T_str()); }
|
||||
case (ty.ty_tag(?tag_id)) {
|
||||
case (ty.ty_tag(?tag_id, _)) {
|
||||
ret llvm.LLVMResolveTypeHandle(cx.tags.get(tag_id).th.llth);
|
||||
}
|
||||
case (ty.ty_box(?t)) {
|
||||
|
|
@ -1445,7 +1445,9 @@ fn iter_structural_ty(@block_ctxt cx,
|
|||
i += 1;
|
||||
}
|
||||
}
|
||||
case (ty.ty_tag(?tid)) {
|
||||
case (ty.ty_tag(?tid, _)) {
|
||||
// TODO: type params!
|
||||
|
||||
check (cx.fcx.ccx.tags.contains_key(tid));
|
||||
auto info = cx.fcx.ccx.tags.get(tid);
|
||||
auto n_variants = _vec.len[tup(ast.def_id,arity)](info.variants);
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ tag sty {
|
|||
ty_machine(util.common.ty_mach);
|
||||
ty_char;
|
||||
ty_str;
|
||||
ty_tag(ast.def_id);
|
||||
ty_tag(ast.def_id, vec[@t]);
|
||||
ty_box(@t);
|
||||
ty_vec(@t);
|
||||
ty_tup(vec[@t]);
|
||||
|
|
@ -42,7 +42,7 @@ tag sty {
|
|||
ty_obj(vec[method]);
|
||||
ty_var(int); // ephemeral type var
|
||||
ty_local(ast.def_id); // type of a local var
|
||||
ty_param(ast.def_id); // fn type param
|
||||
ty_param(ast.def_id); // fn/tag type param
|
||||
ty_type;
|
||||
ty_native;
|
||||
// TODO: ty_fn_arg(@t), for a possibly-aliased function argument
|
||||
|
|
@ -235,9 +235,14 @@ fn ty_to_str(&@t typ) -> str {
|
|||
s = "rec(" + _str.connect(strs, ",") + ")";
|
||||
}
|
||||
|
||||
case (ty_tag(_)) {
|
||||
case (ty_tag(_, ?tps)) {
|
||||
// The user should never see this if the cname is set properly!
|
||||
s = "<tag>";
|
||||
if (_vec.len[@t](tps) > 0u) {
|
||||
auto f = ty_to_str;
|
||||
auto strs = _vec.map[@t,str](f, tps);
|
||||
s += "[" + _str.connect(strs, ",") + "]";
|
||||
}
|
||||
}
|
||||
|
||||
case (ty_fn(?inputs, ?output)) {
|
||||
|
|
@ -291,7 +296,6 @@ fn fold_ty(ty_fold fld, @t ty) -> @t {
|
|||
case (ty_machine(_)) { ret fld.fold_simple_ty(ty); }
|
||||
case (ty_char) { ret fld.fold_simple_ty(ty); }
|
||||
case (ty_str) { ret fld.fold_simple_ty(ty); }
|
||||
case (ty_tag(_)) { ret fld.fold_simple_ty(ty); }
|
||||
case (ty_type) { ret fld.fold_simple_ty(ty); }
|
||||
case (ty_native) { ret fld.fold_simple_ty(ty); }
|
||||
case (ty_box(?subty)) {
|
||||
|
|
@ -300,6 +304,13 @@ fn fold_ty(ty_fold fld, @t ty) -> @t {
|
|||
case (ty_vec(?subty)) {
|
||||
ret rewrap(ty, ty_vec(fold_ty(fld, subty)));
|
||||
}
|
||||
case (ty_tag(?tid, ?subtys)) {
|
||||
let vec[@t] new_subtys = vec();
|
||||
for (@t subty in subtys) {
|
||||
new_subtys += vec(fold_ty(fld, subty));
|
||||
}
|
||||
ret rewrap(ty, ty_tag(tid, new_subtys));
|
||||
}
|
||||
case (ty_tup(?subtys)) {
|
||||
let vec[@t] new_subtys = vec();
|
||||
for (@t subty in subtys) {
|
||||
|
|
@ -364,23 +375,23 @@ fn type_is_nil(@t ty) -> bool {
|
|||
|
||||
fn type_is_structural(@t ty) -> bool {
|
||||
alt (ty.struct) {
|
||||
case (ty_tup(_)) { ret true; }
|
||||
case (ty_rec(_)) { ret true; }
|
||||
case (ty_tag(_)) { ret true; }
|
||||
case (ty_fn(_,_)) { ret true; }
|
||||
case (ty_obj(_)) { ret true; }
|
||||
case (_) { ret false; }
|
||||
case (ty_tup(_)) { ret true; }
|
||||
case (ty_rec(_)) { ret true; }
|
||||
case (ty_tag(_,_)) { ret true; }
|
||||
case (ty_fn(_,_)) { ret true; }
|
||||
case (ty_obj(_)) { ret true; }
|
||||
case (_) { ret false; }
|
||||
}
|
||||
fail;
|
||||
}
|
||||
|
||||
fn type_is_tup_like(@t ty) -> bool {
|
||||
alt (ty.struct) {
|
||||
case (ty_box(_)) { ret true; }
|
||||
case (ty_tup(_)) { ret true; }
|
||||
case (ty_rec(_)) { ret true; }
|
||||
case (ty_tag(_)) { ret true; }
|
||||
case (_) { ret false; }
|
||||
case (ty_box(_)) { ret true; }
|
||||
case (ty_tup(_)) { ret true; }
|
||||
case (ty_rec(_)) { ret true; }
|
||||
case (ty_tag(_,_)) { ret true; }
|
||||
case (_) { ret false; }
|
||||
}
|
||||
fail;
|
||||
}
|
||||
|
|
@ -641,8 +652,13 @@ fn item_ty(@ast.item it) -> ty_params_and_ty {
|
|||
result_ty = ann_to_type(ann);
|
||||
}
|
||||
case (ast.item_tag(_, _, ?tps, ?did)) {
|
||||
// Create a new generic polytype.
|
||||
ty_params = tps;
|
||||
result_ty = plain_ty(ty_tag(did));
|
||||
let vec[@t] subtys = vec();
|
||||
for (ast.ty_param tp in tps) {
|
||||
subtys += vec(plain_ty(ty_param(tp.id)));
|
||||
}
|
||||
result_ty = plain_ty(ty_tag(did, subtys));
|
||||
}
|
||||
case (ast.item_obj(_, _, ?tps, _, ?ann)) {
|
||||
ty_params = tps;
|
||||
|
|
@ -1001,13 +1017,42 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
|
|||
case (ty.ty_type) { ret struct_cmp(expected, actual); }
|
||||
case (ty.ty_native) { ret struct_cmp(expected, actual); }
|
||||
|
||||
case (ty.ty_tag(?expected_id)) {
|
||||
case (ty.ty_tag(?expected_id, ?expected_tps)) {
|
||||
alt (actual.struct) {
|
||||
case (ty.ty_tag(?actual_id)) {
|
||||
if (expected_id._0 == actual_id._0 &&
|
||||
expected_id._1 == actual_id._1) {
|
||||
ret ures_ok(expected);
|
||||
case (ty.ty_tag(?actual_id, ?actual_tps)) {
|
||||
if (expected_id._0 != actual_id._0 ||
|
||||
expected_id._1 != actual_id._1) {
|
||||
ret ures_err(terr_mismatch, expected, actual);
|
||||
}
|
||||
|
||||
// TODO: factor this cruft out, see the TODO in the
|
||||
// ty.ty_tup case
|
||||
let vec[@ty.t] result_tps = vec();
|
||||
auto i = 0u;
|
||||
auto expected_len = _vec.len[@ty.t](expected_tps);
|
||||
while (i < expected_len) {
|
||||
auto expected_tp = expected_tps.(i);
|
||||
auto actual_tp = actual_tps.(i);
|
||||
|
||||
auto result = unify_step(bindings,
|
||||
expected_tp,
|
||||
actual_tp,
|
||||
handler);
|
||||
|
||||
alt (result) {
|
||||
case (ures_ok(?rty)) {
|
||||
append[@ty.t](result_tps, rty);
|
||||
}
|
||||
case (_) {
|
||||
ret result;
|
||||
}
|
||||
}
|
||||
|
||||
i += 1u;
|
||||
}
|
||||
|
||||
ret ures_ok(plain_ty(ty.ty_tag(expected_id,
|
||||
result_tps)));
|
||||
}
|
||||
case (_) { /* fall through */ }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -430,8 +430,13 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
ret ty_;
|
||||
}
|
||||
|
||||
case (ast.item_tag(_, _, _, ?def_id)) {
|
||||
auto t = plain_ty(ty.ty_tag(def_id));
|
||||
case (ast.item_tag(_, _, ?tps, ?def_id)) {
|
||||
// Create a new generic polytype.
|
||||
let vec[@ty.t] subtys = vec();
|
||||
for (ast.ty_param tp in tps) {
|
||||
subtys += vec(plain_ty(ty.ty_param(tp.id)));
|
||||
}
|
||||
auto t = plain_ty(ty.ty_tag(def_id, subtys));
|
||||
item_to_ty.insert(def_id, t);
|
||||
ret t;
|
||||
}
|
||||
|
|
@ -468,15 +473,23 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
fn get_tag_variant_types(@ty_item_table id_to_ty_item,
|
||||
@ty_table item_to_ty,
|
||||
&ast.def_id tag_id,
|
||||
&vec[ast.variant] variants) -> vec[ast.variant] {
|
||||
&vec[ast.variant] variants,
|
||||
&vec[ast.ty_param] ty_params)
|
||||
-> vec[ast.variant] {
|
||||
let vec[ast.variant] result = vec();
|
||||
|
||||
// Create a set of parameter types shared among all the variants.
|
||||
let vec[@ty.t] ty_param_tys = vec();
|
||||
for (ast.ty_param tp in ty_params) {
|
||||
ty_param_tys += vec(plain_ty(ty.ty_param(tp.id)));
|
||||
}
|
||||
|
||||
for (ast.variant variant in variants) {
|
||||
// Nullary tag constructors get truned into constants; n-ary tag
|
||||
// Nullary tag constructors get turned into constants; n-ary tag
|
||||
// constructors get turned into functions.
|
||||
auto result_ty;
|
||||
if (_vec.len[ast.variant_arg](variant.args) == 0u) {
|
||||
result_ty = plain_ty(ty.ty_tag(tag_id));
|
||||
result_ty = plain_ty(ty.ty_tag(tag_id, ty_param_tys));
|
||||
} else {
|
||||
// As above, tell ast_ty_to_ty() that trans_ty_item_to_ty()
|
||||
// should be called to resolve named types.
|
||||
|
|
@ -487,7 +500,7 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
auto arg_ty = ast_ty_to_ty(f, va.ty);
|
||||
args += vec(rec(mode=ast.alias, ty=arg_ty));
|
||||
}
|
||||
auto tag_t = plain_ty(ty.ty_tag(tag_id));
|
||||
auto tag_t = plain_ty(ty.ty_tag(tag_id, ty_param_tys));
|
||||
result_ty = plain_ty(ty.ty_fn(args, tag_t));
|
||||
}
|
||||
|
||||
|
|
@ -674,7 +687,9 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
ast.def_id id) -> @ast.item {
|
||||
auto variants_t = get_tag_variant_types(e.id_to_ty_item,
|
||||
e.item_to_ty,
|
||||
id, variants);
|
||||
id,
|
||||
variants,
|
||||
ty_params);
|
||||
auto item = ast.item_tag(i, variants_t, ty_params, id);
|
||||
ret @fold.respan[ast.item_](sp, item);
|
||||
}
|
||||
|
|
@ -857,7 +872,7 @@ fn demand_pat(&@fn_ctxt fcx, @ty.t expected, @ast.pat pat) -> @ast.pat {
|
|||
|
||||
auto subpats_len = _vec.len[@ast.pat](subpats);
|
||||
alt (variant_ty.struct) {
|
||||
case (ty.ty_tag(_)) {
|
||||
case (ty.ty_tag(_, _)) {
|
||||
// Nullary tag variant.
|
||||
check (subpats_len == 0u);
|
||||
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 {
|
|||
}
|
||||
|
||||
// Nullary variants have tag types.
|
||||
case (ty.ty_tag(?tid)) {
|
||||
case (ty.ty_tag(?tid, _)) {
|
||||
// TODO: ty params
|
||||
|
||||
auto subpats_len = _vec.len[@ast.pat](subpats);
|
||||
if (subpats_len > 0u) {
|
||||
// TODO: pluralize properly
|
||||
|
|
@ -1212,7 +1229,8 @@ fn check_pat(&@fn_ctxt fcx, @ast.pat pat) -> @ast.pat {
|
|||
fail; // TODO: recover
|
||||
}
|
||||
|
||||
auto ann = ast.ann_type(plain_ty(ty.ty_tag(tid)));
|
||||
let vec[@ty.t] tys = vec(); // FIXME
|
||||
auto ann = ast.ann_type(plain_ty(ty.ty_tag(tid, tys)));
|
||||
new_pat = ast.pat_tag(p, subpats, vdef_opt, ann);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,4 +6,4 @@ tag option[T] {
|
|||
fn main() {
|
||||
let option[int] a = some[int](@10);
|
||||
a = none[int];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue