From ef50d0e668635824cc5ed86aaa385dd6f3181b53 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Mon, 31 Jan 2011 18:06:35 -0800 Subject: More work on derived tydescs. Can compile simple tests with generic objects. --- src/comp/middle/ty.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index f27595a1..7a184bc6 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -571,7 +571,8 @@ fn is_fn_ty(@t fty) -> bool { // Given an item, returns the associated type as well as a list of the IDs of // its type parameters. -fn item_ty(@ast.item it) -> tup(vec[ast.def_id], @t) { +type ty_params_and_ty = tup(vec[ast.def_id], @t); +fn item_ty(@ast.item it) -> ty_params_and_ty { let vec[ast.ty_param] ty_params; auto result_ty; alt (it.node) { @@ -1233,7 +1234,8 @@ fn type_err_to_str(&ty.type_err err) -> str { // Type parameter resolution, used in translation -fn resolve_ty_params(@ast.item item, @t monoty) -> vec[@t] { +fn resolve_ty_params(ty_params_and_ty ty_params_and_polyty, + @t monoty) -> vec[@t] { obj resolve_ty_params_handler(@hashmap[ast.def_id,@t] bindings) { fn resolve_local(ast.def_id id) -> @t { log "resolve local"; fail; } fn record_local(ast.def_id id, @t ty) { log "record local"; fail; } @@ -1249,8 +1251,6 @@ fn resolve_ty_params(@ast.item item, @t monoty) -> vec[@t] { } } - auto ty_params_and_polyty = item_ty(item); - auto bindings = @new_def_hash[@t](); auto handler = resolve_ty_params_handler(bindings); -- cgit v1.2.3 From 8ef22972dbe50b2e05c8983769a638fd5b6a23b5 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Tue, 1 Feb 2011 14:56:21 -0800 Subject: Add ty_type. --- src/comp/middle/ty.rs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 7a184bc6..b840be91 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -42,6 +42,7 @@ tag sty { 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_type; // TODO: ty_fn_arg(@t), for a possibly-aliased function argument } @@ -103,6 +104,7 @@ fn ast_ty_to_str(&@ast.ty ty) -> str { case (ast.ty_str) { s = "str"; } case (ast.ty_box(?t)) { s = "@" + ast_ty_to_str(t); } case (ast.ty_vec(?t)) { s = "vec[" + ast_ty_to_str(t) + "]"; } + case (ast.ty_type) { s = "type"; } case (ast.ty_tup(?elts)) { auto f = ast_ty_to_str; @@ -138,6 +140,7 @@ fn ast_ty_to_str(&@ast.ty ty) -> str { s = "mutable " + ast_ty_to_str(t); } + case (_) { fail; // FIXME: typestate bug } @@ -215,6 +218,7 @@ fn ty_to_str(&@t typ) -> str { case (ty_str) { s = "str"; } case (ty_box(?t)) { s = "@" + ty_to_str(t); } case (ty_vec(?t)) { s = "vec[" + ty_to_str(t) + "]"; } + case (ty_type) { s = "type"; } case (ty_tup(?elems)) { auto f = ty_to_str; @@ -281,6 +285,7 @@ fn fold_ty(ty_fold fld, @t ty) -> @t { 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_box(?subty)) { ret rewrap(ty, ty_box(fold_ty(fld, subty))); } @@ -363,6 +368,7 @@ fn type_is_structural(@t ty) -> bool { 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; } @@ -402,6 +408,7 @@ fn type_is_scalar(@t ty) -> bool { case (ty_uint) { ret true; } case (ty_machine(_)) { ret true; } case (ty_char) { ret true; } + case (ty_type) { ret true; } case (_) { ret false; } } fail; @@ -939,6 +946,7 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) case (ty.ty_machine(_)) { ret struct_cmp(expected, actual); } case (ty.ty_char) { ret struct_cmp(expected, actual); } case (ty.ty_str) { ret struct_cmp(expected, actual); } + case (ty.ty_type) { ret struct_cmp(expected, actual); } case (ty.ty_tag(?expected_id)) { alt (actual.struct) { -- cgit v1.2.3 From 70bf54bcac587c0bc8a3a593bda75115e4c23aa8 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Tue, 1 Feb 2011 16:23:48 -0800 Subject: Implement 'else if' --- src/comp/middle/ty.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index b840be91..2f14aae6 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -653,7 +653,7 @@ fn expr_ty(@ast.expr expr) -> @t { case (ast.expr_unary(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_lit(_, ?ann)) { ret ann_to_type(ann); } case (ast.expr_cast(_, _, ?ann)) { ret ann_to_type(ann); } - case (ast.expr_if(_, _, _, ?ann)) { ret ann_to_type(ann); } + case (ast.expr_if(_, _, _, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_for(_, _, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_while(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_do_while(_, _, ?ann)) { ret ann_to_type(ann); } -- cgit v1.2.3 From d7f118135b8a3eee7c8788052542e6e1c205a3d9 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Mon, 7 Feb 2011 14:11:43 -0800 Subject: Iterate type unification to drive the types a bit further down into the leaves of results with residual vars. Cheap but kinda works. --- src/comp/middle/ty.rs | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 2f14aae6..92fa1399 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -551,6 +551,24 @@ fn count_ty_params(@t ty) -> uint { ret _vec.len[ast.def_id](*param_ids); } +fn type_contains_ty_vars(@t ty) -> bool { + state obj checker(@mutable bool has_vars) { + fn fold_simple_ty(@t ty) -> @t { + alt (ty.struct) { + case (ty_var(_)) { + *has_vars = true; + } + case (_) {} + } + ret ty; + } + } + + let @mutable bool b = @mutable false; + fold_ty(checker(b), ty); + ret *b; +} + // Type accessors for substructures of types fn ty_fn_args(@t fty) -> vec[arg] { @@ -1197,7 +1215,21 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) auto eqer = eq_int; auto bindings = map.mk_hashmap[int,@ty.t](hasher, eqer); - ret unify_step(bindings, expected, actual, handler); + auto ures = unify_step(bindings, expected, actual, handler); + while (true) { + alt (ures) { + case (ures_ok(?t)) { + if (!type_contains_ty_vars(t)) { + ret ures; + } + ures = unify_step(bindings, t, actual, handler); + } + case (_) { + ret ures; + } + } + } + fail; } fn type_err_to_str(&ty.type_err err) -> str { -- cgit v1.2.3 From 9d576993f31349f2a7dbf8e40ccdaff9cf66144d Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Mon, 7 Feb 2011 14:16:40 -0800 Subject: Add a fixme for last commit. --- src/comp/middle/ty.rs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 92fa1399..c3b0e687 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -1215,6 +1215,10 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) auto eqer = eq_int; auto bindings = map.mk_hashmap[int,@ty.t](hasher, eqer); + // FIXME: this is a slow way of driving types into residual vars that + // occur up in the leaves of result type; it can likely be done better + // when unification is actually ... down in the leaves. + auto ures = unify_step(bindings, expected, actual, handler); while (true) { alt (ures) { -- cgit v1.2.3 From 0d27eb13415d442a4f643c8cf4c0d839c0460744 Mon Sep 17 00:00:00 2001 From: Rafael Avila de Espindola Date: Thu, 10 Feb 2011 18:39:55 -0500 Subject: Add type checking for native types. --- src/comp/middle/ty.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index c3b0e687..6dd229fb 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -43,6 +43,7 @@ tag sty { ty_local(ast.def_id); // type of a local var ty_param(ast.def_id); // fn type param ty_type; + ty_native; // TODO: ty_fn_arg(@t), for a possibly-aliased function argument } @@ -286,6 +287,7 @@ fn fold_ty(ty_fold fld, @t ty) -> @t { 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)) { ret rewrap(ty, ty_box(fold_ty(fld, subty))); } -- cgit v1.2.3 From c9956a65b49f9cf2b1a691f2b88d61ada753d271 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Thu, 10 Feb 2011 19:22:30 -0800 Subject: Teach ty and typeck about pat_lit. --- src/comp/middle/ty.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 6dd229fb..2bb65fe0 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -656,6 +656,7 @@ fn block_ty(&ast.block b) -> @t { fn pat_ty(@ast.pat pat) -> @t { alt (pat.node) { case (ast.pat_wild(?ann)) { ret ann_to_type(ann); } + case (ast.pat_lit(_, ?ann)) { ret ann_to_type(ann); } case (ast.pat_bind(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.pat_tag(_, _, _, ?ann)) { ret ann_to_type(ann); } } -- cgit v1.2.3 From bd56dd9f2aca1967c92d3cc613dcc199c878026c Mon Sep 17 00:00:00 2001 From: Rafael Avila de Espindola Date: Mon, 14 Feb 2011 11:22:10 -0500 Subject: Add missing case to unify. This gets hello world to codegen. --- src/comp/middle/ty.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 2bb65fe0..b9753474 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -968,6 +968,7 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) case (ty.ty_char) { ret struct_cmp(expected, actual); } case (ty.ty_str) { ret struct_cmp(expected, actual); } case (ty.ty_type) { ret struct_cmp(expected, actual); } + case (ty.ty_native) { ret struct_cmp(expected, actual); } case (ty.ty_tag(?expected_id)) { alt (actual.struct) { -- cgit v1.2.3 From 59bce06a967b3806c3d874b8956857f0f01287e1 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Mon, 14 Feb 2011 15:52:38 -0800 Subject: Expand expr_rec to take its optional trailing 'with' parameter. --- src/comp/middle/ty.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index b9753474..2083ef2b 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -667,7 +667,7 @@ fn expr_ty(@ast.expr expr) -> @t { alt (expr.node) { case (ast.expr_vec(_, ?ann)) { ret ann_to_type(ann); } case (ast.expr_tup(_, ?ann)) { ret ann_to_type(ann); } - case (ast.expr_rec(_, ?ann)) { ret ann_to_type(ann); } + case (ast.expr_rec(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_bind(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_call(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_binary(_, _, _, ?ann)) { ret ann_to_type(ann); } -- cgit v1.2.3 From f1f33abdeba156523d6db1752bbff75dc4088724 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Mon, 14 Feb 2011 17:46:28 -0800 Subject: Move all non-decl/non-expr stmts to exprs. --- src/comp/middle/ty.rs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 2083ef2b..58529d0d 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -686,6 +686,12 @@ fn expr_ty(@ast.expr expr) -> @t { case (ast.expr_field(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_index(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_path(_, _, ?ann)) { ret ann_to_type(ann); } + + case (ast.expr_fail) { ret plain_ty(ty_nil); } + case (ast.expr_log(_)) { ret plain_ty(ty_nil); } + case (ast.expr_check_expr(_)) { ret plain_ty(ty_nil); } + case (ast.expr_ret(_)) { ret plain_ty(ty_nil); } + case (ast.expr_be(_)) { ret plain_ty(ty_nil); } } fail; } -- cgit v1.2.3 From 15a01f5c3691a152793d8933a7be9d16a0fc7030 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Mon, 14 Feb 2011 17:58:32 -0800 Subject: Add basic front-end support for expr_put. --- src/comp/middle/ty.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 58529d0d..f9b2bd9d 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -691,6 +691,7 @@ fn expr_ty(@ast.expr expr) -> @t { case (ast.expr_log(_)) { ret plain_ty(ty_nil); } case (ast.expr_check_expr(_)) { ret plain_ty(ty_nil); } case (ast.expr_ret(_)) { ret plain_ty(ty_nil); } + case (ast.expr_put(_)) { ret plain_ty(ty_nil); } case (ast.expr_be(_)) { ret plain_ty(ty_nil); } } fail; -- cgit v1.2.3 From 4a72a23171d87fb5a0f9b7ad039944856b93bf0f Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Mon, 14 Feb 2011 18:17:31 -0800 Subject: Add basic front-end support for 'for each' loops. --- src/comp/middle/ty.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index f9b2bd9d..499ed74d 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -676,6 +676,8 @@ fn expr_ty(@ast.expr expr) -> @t { case (ast.expr_cast(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_if(_, _, _, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_for(_, _, _, ?ann)) { ret ann_to_type(ann); } + case (ast.expr_for_each(_, _, _, ?ann)) + { ret ann_to_type(ann); } case (ast.expr_while(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_do_while(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_alt(_, _, ?ann)) { ret ann_to_type(ann); } -- cgit v1.2.3 From 012fa69ea500aa31cb3dd2cd3df67ecd3eefd44e Mon Sep 17 00:00:00 2001 From: Rafael Avila de Espindola Date: Wed, 16 Feb 2011 14:02:02 -0500 Subject: More typechecking for native types and the needed plumbing in codegen. --- src/comp/middle/ty.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 499ed74d..21b68fb5 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -599,6 +599,22 @@ fn is_fn_ty(@t fty) -> bool { // Given an item, returns the associated type as well as a list of the IDs of // its type parameters. type ty_params_and_ty = tup(vec[ast.def_id], @t); +fn native_item_ty(@ast.native_item it) -> ty_params_and_ty { + auto ty_params; + auto result_ty; + alt (it.node) { + case (ast.native_item_fn(_, _, ?tps, _, ?ann)) { + ty_params = tps; + result_ty = ann_to_type(ann); + } + } + let vec[ast.def_id] ty_param_ids = vec(); + for (ast.ty_param tp in ty_params) { + ty_param_ids += vec(tp.id); + } + ret tup(ty_param_ids, result_ty); +} + fn item_ty(@ast.item it) -> ty_params_and_ty { let vec[ast.ty_param] ty_params; auto result_ty; -- cgit v1.2.3 From 293637139fe55990397849badfb60c96d4211b31 Mon Sep 17 00:00:00 2001 From: Rafael Avila de Espindola Date: Wed, 16 Feb 2011 15:00:40 -0500 Subject: Add missing case to ty_to_str. Disable test that now fails because we produce undefined references to the native functions. --- src/comp/middle/ty.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 21b68fb5..a9be0c36 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -210,6 +210,7 @@ fn ty_to_str(&@t typ) -> str { } alt (typ.struct) { + case (ty_native) { s = "native"; } case (ty_nil) { s = "()"; } case (ty_bool) { s = "bool"; } case (ty_int) { s = "int"; } -- cgit v1.2.3 From 07c7888037cb74ca33459946145608a854aae6ed Mon Sep 17 00:00:00 2001 From: Rafael Avila de Espindola Date: Wed, 16 Feb 2011 16:16:11 -0500 Subject: Don't add the rust arguments to native functions. We now produce the correct arguments for native functions. --- src/comp/middle/ty.rs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index a9be0c36..adda5a8c 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -38,6 +38,7 @@ tag sty { ty_tup(vec[@t]); ty_rec(vec[field]); ty_fn(vec[arg], @t); // TODO: effect + ty_native_fn(vec[arg], @t); // TODO: effect ty_obj(vec[method]); ty_var(int); // ephemeral type var ty_local(ast.def_id); // type of a local var @@ -243,6 +244,10 @@ fn ty_to_str(&@t typ) -> str { s = fn_to_str(none[ast.ident], inputs, output); } + case (ty_native_fn(?inputs, ?output)) { + s = fn_to_str(none[ast.ident], inputs, output); + } + case (ty_obj(?meths)) { auto f = method_to_str; auto m = _vec.map[method,str](f, meths); -- cgit v1.2.3 From 10befcd9a4d9f68e2dbec84c4a86450a021143fb Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 17 Feb 2011 16:23:31 -0800 Subject: Add type parameters to tag types --- src/comp/middle/ty.rs | 87 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 21 deletions(-) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index adda5a8c..e8f5b046 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -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 = ""; + 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 */ } } -- cgit v1.2.3 From 3aba50ff331f4d97b1ca2a60091b03e012837b98 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 18 Feb 2011 14:52:33 -0800 Subject: Implement Robinson's algorithm for type unification. Closes #227. --- src/comp/middle/ty.rs | 145 ++++++++++++++++++++++++-------------------------- 1 file changed, 70 insertions(+), 75 deletions(-) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index e8f5b046..a9a4e936 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -570,24 +570,6 @@ fn count_ty_params(@t ty) -> uint { ret _vec.len[ast.def_id](*param_ids); } -fn type_contains_ty_vars(@t ty) -> bool { - state obj checker(@mutable bool has_vars) { - fn fold_simple_ty(@t ty) -> @t { - alt (ty.struct) { - case (ty_var(_)) { - *has_vars = true; - } - case (_) {} - } - ret ty; - } - } - - let @mutable bool b = @mutable false; - fold_ty(checker(b), ty); - ret *b; -} - // Type accessors for substructures of types fn ty_fn_args(@t fty) -> vec[arg] { @@ -802,7 +784,10 @@ fn is_lval(@ast.expr expr) -> bool { } } -// Type unification +// Type unification via Robinson's algorithm (Robinson 1965). Implemented as +// described in Hoder and Voronkov: +// +// http://www.cs.man.ac.uk/~hoderk/ubench/unification_full.pdf fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) -> unify_result { @@ -822,7 +807,7 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) ret ures_err(terr_mismatch, expected, actual); } - fn unify_fn(&hashmap[int,@ty.t] bindings, + fn unify_fn(@hashmap[int,@ty.t] bindings, @ty.t expected, @ty.t actual, &unify_handler handler, @@ -891,7 +876,7 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) } - fn unify_obj(&hashmap[int,@ty.t] bindings, + fn unify_obj(@hashmap[int,@ty.t] bindings, @ty.t expected, @ty.t actual, &unify_handler handler, @@ -952,27 +937,44 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) ret ures_ok(t); } - fn unify_step(&hashmap[int,@ty.t] bindings, @ty.t expected, @ty.t actual, - &unify_handler handler) -> unify_result { + fn resolve(@hashmap[int,@t] bindings, @t typ) -> @t { + alt (typ.struct) { + case (ty_var(?id)) { + alt (bindings.find(id)) { + case (some[@t](?typ2)) { + ret resolve(bindings, typ2); + } + case (none[@t]) { + // fall through + } + } + } + case (_) { + // fall through + } + } + ret typ; + } + + fn unify_step(@hashmap[int,@ty.t] bindings, @ty.t in_expected, + @ty.t in_actual, &unify_handler handler) -> unify_result { + + // Resolve any bindings. + auto expected = resolve(bindings, in_expected); + auto actual = resolve(bindings, in_actual); + // TODO: rewrite this using tuple pattern matching when available, to // avoid all this rightward drift and spikiness. + // TODO: occurs check, to make sure we don't loop forever when + // unifying e.g. 'a and option['a] + alt (actual.struct) { // If the RHS is a variable type, then just do the appropriate // binding. case (ty.ty_var(?actual_id)) { - alt (bindings.find(actual_id)) { - case (some[@ty.t](?actual_ty)) { - // FIXME: change the binding here? - // FIXME: "be" - ret unify_step(bindings, expected, actual_ty, - handler); - } - case (none[@ty.t]) { - bindings.insert(actual_id, expected); - ret ures_ok(expected); - } - } + bindings.insert(actual_id, expected); + ret ures_ok(expected); } case (ty.ty_local(?actual_id)) { auto actual_ty = handler.resolve_local(actual_id); @@ -1077,8 +1079,6 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) } } - // TODO: ty_var - case (_) { ret ures_err(terr_mismatch, expected, actual); } @@ -1102,8 +1102,6 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) } } - // TODO: ty_var - case (_) { ret ures_err(terr_mismatch, expected, actual); } @@ -1152,8 +1150,6 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) ret ures_ok(plain_ty(ty.ty_tup(result_elems))); } - // TODO: ty_var - case (_) { ret ures_err(terr_mismatch, expected, actual); } @@ -1213,8 +1209,6 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) ret ures_ok(plain_ty(ty.ty_rec(result_fields))); } - // TODO: ty_var - case (_) { ret ures_err(terr_mismatch, expected, actual); } @@ -1248,20 +1242,9 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) } case (ty.ty_var(?expected_id)) { - alt (bindings.find(expected_id)) { - case (some[@ty.t](?expected_ty)) { - // FIXME: change the binding here? - // FIXME: "be" - ret unify_step(bindings, - expected_ty, - actual, - handler); - } - case (none[@ty.t]) { - bindings.insert(expected_id, actual); - ret ures_ok(actual); - } - } + // Add a binding. + bindings.insert(expected_id, actual); + ret ures_ok(actual); } case (ty.ty_local(?expected_id)) { @@ -1289,31 +1272,43 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) fail; } + // Performs type binding substitution. + fn substitute(@hashmap[int,@t] bindings, @t typ) -> @t { + state obj folder(@hashmap[int,@t] bindings) { + fn fold_simple_ty(@t typ) -> @t { + alt (typ.struct) { + case (ty_var(?id)) { + alt (bindings.find(id)) { + case (some[@t](?typ2)) { + ret substitute(bindings, typ2); + } + case (none[@t]) { + ret typ; + } + } + } + case (_) { + ret typ; + } + } + } + } + + ret ty.fold_ty(folder(bindings), typ); + } + fn hash_int(&int x) -> uint { ret x as uint; } fn eq_int(&int a, &int b) -> bool { ret a == b; } auto hasher = hash_int; auto eqer = eq_int; - auto bindings = map.mk_hashmap[int,@ty.t](hasher, eqer); - - // FIXME: this is a slow way of driving types into residual vars that - // occur up in the leaves of result type; it can likely be done better - // when unification is actually ... down in the leaves. + auto bindings = @map.mk_hashmap[int,@ty.t](hasher, eqer); auto ures = unify_step(bindings, expected, actual, handler); - while (true) { - alt (ures) { - case (ures_ok(?t)) { - if (!type_contains_ty_vars(t)) { - ret ures; - } - ures = unify_step(bindings, t, actual, handler); - } - case (_) { - ret ures; - } - } + alt (ures) { + case (ures_ok(?t)) { ret ures_ok(substitute(bindings, t)); } + case (_) { ret ures; } } - fail; + fail; // not reached } fn type_err_to_str(&ty.type_err err) -> str { -- cgit v1.2.3 From 34c60b6edb810d9f142d248b27d8e6e34c95d63c Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Fri, 18 Feb 2011 17:30:57 -0800 Subject: Make a tag for iterness / fnness, teach many places about it. --- src/comp/middle/ty.rs | 243 ++++++++++++++++++++++++++++---------------------- 1 file changed, 136 insertions(+), 107 deletions(-) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index a9a4e936..68c21140 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -19,7 +19,10 @@ import util.common.span; type arg = rec(ast.mode mode, @t ty); type field = rec(ast.ident ident, @t ty); -type method = rec(ast.ident ident, vec[arg] inputs, @t output); +type method = rec(ast.proto proto, + ast.ident ident, + vec[arg] inputs, + @t output); // NB: If you change this, you'll probably want to change the corresponding // AST structure in front/ast.rs as well. @@ -37,7 +40,7 @@ tag sty { ty_vec(@t); ty_tup(vec[@t]); ty_rec(vec[field]); - ty_fn(vec[arg], @t); // TODO: effect + ty_fn(ast.proto, vec[arg], @t); // TODO: effect ty_native_fn(vec[arg], @t); // TODO: effect ty_obj(vec[method]); ty_var(int); // ephemeral type var @@ -122,9 +125,13 @@ fn ast_ty_to_str(&@ast.ty ty) -> str { s += ")"; } - case (ast.ty_fn(?inputs, ?output)) { + case (ast.ty_fn(?proto, ?inputs, ?output)) { auto f = ast_fn_input_to_str; - s = "fn("; + if (proto == ast.proto_fn) { + s = "fn("; + } else { + s = "iter("; + } auto is = _vec.map[rec(ast.mode mode, @ast.ty ty),str](f, inputs); s += _str.connect(is, ", "); s += ")"; @@ -175,10 +182,14 @@ fn ty_to_str(&@t typ) -> str { ret s + ty_to_str(input.ty); } - fn fn_to_str(option.t[ast.ident] ident, + fn fn_to_str(ast.proto proto, + option.t[ast.ident] ident, vec[arg] inputs, @t output) -> str { auto f = fn_input_to_str; auto s = "fn"; + if (proto == ast.proto_iter) { + s = "iter"; + } alt (ident) { case (some[ast.ident](?i)) { s += " "; @@ -198,7 +209,8 @@ fn ty_to_str(&@t typ) -> str { } fn method_to_str(&method m) -> str { - ret fn_to_str(some[ast.ident](m.ident), m.inputs, m.output) + ";"; + ret fn_to_str(m.proto, some[ast.ident](m.ident), + m.inputs, m.output) + ";"; } fn field_to_str(&field f) -> str { @@ -245,12 +257,12 @@ fn ty_to_str(&@t typ) -> str { } } - case (ty_fn(?inputs, ?output)) { - s = fn_to_str(none[ast.ident], inputs, output); + case (ty_fn(?proto, ?inputs, ?output)) { + s = fn_to_str(proto, none[ast.ident], inputs, output); } case (ty_native_fn(?inputs, ?output)) { - s = fn_to_str(none[ast.ident], inputs, output); + s = fn_to_str(ast.proto_fn, none[ast.ident], inputs, output); } case (ty_obj(?meths)) { @@ -326,13 +338,13 @@ fn fold_ty(ty_fold fld, @t ty) -> @t { } ret rewrap(ty, ty_rec(new_fields)); } - case (ty_fn(?args, ?ret_ty)) { + case (ty_fn(?proto, ?args, ?ret_ty)) { let vec[arg] new_args = vec(); for (arg a in args) { auto new_ty = fold_ty(fld, a.ty); new_args += vec(rec(mode=a.mode, ty=new_ty)); } - ret rewrap(ty, ty_fn(new_args, fold_ty(fld, ret_ty))); + ret rewrap(ty, ty_fn(proto, new_args, fold_ty(fld, ret_ty))); } case (ty_obj(?methods)) { let vec[method] new_methods = vec(); @@ -341,7 +353,8 @@ fn fold_ty(ty_fold fld, @t ty) -> @t { for (arg a in m.inputs) { new_args += vec(rec(mode=a.mode, ty=fold_ty(fld, a.ty))); } - new_methods += vec(rec(ident=m.ident, inputs=new_args, + new_methods += vec(rec(proto=m.proto, ident=m.ident, + inputs=new_args, output=fold_ty(fld, m.output))); } ret rewrap(ty, ty_obj(new_methods)); @@ -378,7 +391,7 @@ fn type_is_structural(@t ty) -> bool { case (ty_tup(_)) { ret true; } case (ty_rec(_)) { ret true; } case (ty_tag(_,_)) { ret true; } - case (ty_fn(_,_)) { ret true; } + case (ty_fn(_,_,_)) { ret true; } case (ty_obj(_)) { ret true; } case (_) { ret false; } } @@ -573,23 +586,29 @@ fn count_ty_params(@t ty) -> uint { // Type accessors for substructures of types fn ty_fn_args(@t fty) -> vec[arg] { - alt (fty.struct) { - case (ty.ty_fn(?a, _)) { ret a; } - } + alt (fty.struct) { + case (ty.ty_fn(_, ?a, _)) { ret a; } + } +} + +fn ty_fn_proto(@t fty) -> ast.proto { + alt (fty.struct) { + case (ty.ty_fn(?p, _, _)) { ret p; } + } } fn ty_fn_ret(@t fty) -> @t { - alt (fty.struct) { - case (ty.ty_fn(_, ?r)) { ret r; } - } + alt (fty.struct) { + case (ty.ty_fn(_, _, ?r)) { ret r; } + } } fn is_fn_ty(@t fty) -> bool { - alt (fty.struct) { - case (ty.ty_fn(_, _)) { ret true; } - case (_) { ret false; } - } - ret false; + alt (fty.struct) { + case (ty.ty_fn(_, _, _)) { ret true; } + case (_) { ret false; } + } + ret false; } @@ -808,80 +827,87 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) } fn unify_fn(@hashmap[int,@ty.t] bindings, + ast.proto e_proto, + ast.proto a_proto, @ty.t expected, @ty.t actual, &unify_handler handler, vec[arg] expected_inputs, @t expected_output, vec[arg] actual_inputs, @t actual_output) - -> unify_result { - auto expected_len = _vec.len[arg](expected_inputs); - auto actual_len = _vec.len[arg](actual_inputs); - if (expected_len != actual_len) { - ret ures_err(terr_arg_count, expected, actual); - } + -> unify_result { - // TODO: as above, we should have an iter2 iterator. - let vec[arg] result_ins = vec(); - auto i = 0u; - while (i < expected_len) { - auto expected_input = expected_inputs.(i); - auto actual_input = actual_inputs.(i); - - // This should be safe, I think? - auto result_mode; - if (mode_is_alias(expected_input.mode) || - mode_is_alias(actual_input.mode)) { - result_mode = ast.alias; - } else { - result_mode = ast.val; + if (e_proto != a_proto) { + ret ures_err(terr_mismatch, expected, actual); } - auto result = unify_step(bindings, - actual_input.ty, - expected_input.ty, - handler); + auto expected_len = _vec.len[arg](expected_inputs); + auto actual_len = _vec.len[arg](actual_inputs); + if (expected_len != actual_len) { + ret ures_err(terr_arg_count, expected, actual); + } - alt (result) { - case (ures_ok(?rty)) { - result_ins += vec(rec(mode=result_mode, - ty=rty)); - } + // TODO: as above, we should have an iter2 iterator. + let vec[arg] result_ins = vec(); + auto i = 0u; + while (i < expected_len) { + auto expected_input = expected_inputs.(i); + auto actual_input = actual_inputs.(i); - case (_) { - ret result; - } - } + // This should be safe, I think? + auto result_mode; + if (mode_is_alias(expected_input.mode) || + mode_is_alias(actual_input.mode)) { + result_mode = ast.alias; + } else { + result_mode = ast.val; + } - i += 1u; - } + auto result = unify_step(bindings, + actual_input.ty, + expected_input.ty, + handler); - // Check the output. - auto result_out; - auto result = unify_step(bindings, - expected_output, - actual_output, - handler); - alt (result) { - case (ures_ok(?rty)) { - result_out = rty; + alt (result) { + case (ures_ok(?rty)) { + result_ins += vec(rec(mode=result_mode, + ty=rty)); + } + + case (_) { + ret result; + } + } + + i += 1u; } - case (_) { - ret result; + // Check the output. + auto result_out; + auto result = unify_step(bindings, + expected_output, + actual_output, + handler); + alt (result) { + case (ures_ok(?rty)) { + result_out = rty; + } + + case (_) { + ret result; + } } - } - auto t = plain_ty(ty.ty_fn(result_ins, result_out)); - ret ures_ok(t); + auto t = plain_ty(ty.ty_fn(e_proto, result_ins, result_out)); + ret ures_ok(t); } fn unify_obj(@hashmap[int,@ty.t] bindings, - @ty.t expected, - @ty.t actual, - &unify_handler handler, - vec[method] expected_meths, - vec[method] actual_meths) -> unify_result { + @ty.t expected, + @ty.t actual, + &unify_handler handler, + vec[method] expected_meths, + vec[method] actual_meths) -> unify_result { let vec[method] result_meths = vec(); let uint i = 0u; let uint expected_len = _vec.len[method](expected_meths); @@ -893,28 +919,28 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) // FIXME: work around buggy typestate logic for 'alt', sigh. fn is_ok(&unify_result r) -> bool { - alt (r) { - case (ures_ok(?tfn)) { - ret true; + alt (r) { + case (ures_ok(?tfn)) { + ret true; + } + case (_) {} } - case (_) {} - } - ret false; + ret false; } fn append_if_ok(&method e_meth, &unify_result r, &mutable vec[method] result_meths) { - alt (r) { - case (ures_ok(?tfn)) { - alt (tfn.struct) { - case (ty_fn(?ins, ?out)) { - result_meths += vec(rec(inputs = ins, - output = out - with e_meth)); + alt (r) { + case (ures_ok(?tfn)) { + alt (tfn.struct) { + case (ty_fn(?proto, ?ins, ?out)) { + result_meths += vec(rec(inputs = ins, + output = out + with e_meth)); + } + } } - } } - } } while (i < expected_len) { @@ -924,7 +950,9 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) ret ures_err(terr_obj_meths(e_meth.ident, a_meth.ident), expected, actual); } - auto r = unify_fn(bindings, expected, actual, handler, + auto r = unify_fn(bindings, + e_meth.proto, a_meth.proto, + expected, actual, handler, e_meth.inputs, e_meth.output, a_meth.inputs, a_meth.output); if (!is_ok(r)) { @@ -1215,12 +1243,13 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) } } - case (ty.ty_fn(?expected_inputs, ?expected_output)) { + case (ty.ty_fn(?ep, ?expected_inputs, ?expected_output)) { alt (actual.struct) { - case (ty.ty_fn(?actual_inputs, ?actual_output)) { - ret unify_fn(bindings, expected, actual, handler, - expected_inputs, expected_output, - actual_inputs, actual_output); + case (ty.ty_fn(?ap, ?actual_inputs, ?actual_output)) { + ret unify_fn(bindings, ep, ap, + expected, actual, handler, + expected_inputs, expected_output, + actual_inputs, actual_output); } case (_) { @@ -1230,15 +1259,15 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) } case (ty.ty_obj(?expected_meths)) { - alt (actual.struct) { - case (ty.ty_obj(?actual_meths)) { - ret unify_obj(bindings, expected, actual, handler, - expected_meths, actual_meths); - } - case (_) { - ret ures_err(terr_mismatch, expected, actual); + alt (actual.struct) { + case (ty.ty_obj(?actual_meths)) { + ret unify_obj(bindings, expected, actual, handler, + expected_meths, actual_meths); + } + case (_) { + ret ures_err(terr_mismatch, expected, actual); + } } - } } case (ty.ty_var(?expected_id)) { -- cgit v1.2.3 From 6849abcf7df583f58f390eb55c7b0e84dfb1bd25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20=C3=81vila=20de=20Esp=C3=ADndola?= Date: Wed, 23 Feb 2011 11:59:07 -0500 Subject: Handle the new ty_native_fn in type check. --- src/comp/middle/ty.rs | 107 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 87 insertions(+), 20 deletions(-) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 68c21140..0f277329 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -346,6 +346,14 @@ fn fold_ty(ty_fold fld, @t ty) -> @t { } ret rewrap(ty, ty_fn(proto, new_args, fold_ty(fld, ret_ty))); } + case (ty_native_fn(?args, ?ret_ty)) { + let vec[arg] new_args = vec(); + for (arg a in args) { + auto new_ty = fold_ty(fld, a.ty); + new_args += vec(rec(mode=a.mode, ty=new_ty)); + } + ret rewrap(ty, ty_native_fn(new_args, fold_ty(fld, ret_ty))); + } case (ty_obj(?methods)) { let vec[method] new_methods = vec(); for (method m in methods) { @@ -588,6 +596,7 @@ fn count_ty_params(@t ty) -> uint { fn ty_fn_args(@t fty) -> vec[arg] { alt (fty.struct) { case (ty.ty_fn(_, ?a, _)) { ret a; } + case (ty.ty_native_fn(?a, _)) { ret a; } } } @@ -600,12 +609,14 @@ fn ty_fn_proto(@t fty) -> ast.proto { fn ty_fn_ret(@t fty) -> @t { alt (fty.struct) { case (ty.ty_fn(_, _, ?r)) { ret r; } + case (ty.ty_native_fn(_, ?r)) { ret r; } } } fn is_fn_ty(@t fty) -> bool { alt (fty.struct) { case (ty.ty_fn(_, _, _)) { ret true; } + case (ty.ty_native_fn(_, _)) { ret true; } case (_) { ret false; } } ret false; @@ -826,24 +837,23 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) ret ures_err(terr_mismatch, expected, actual); } - fn unify_fn(@hashmap[int,@ty.t] bindings, - ast.proto e_proto, - ast.proto a_proto, - @ty.t expected, - @ty.t actual, - &unify_handler handler, - vec[arg] expected_inputs, @t expected_output, - vec[arg] actual_inputs, @t actual_output) - -> unify_result { - - if (e_proto != a_proto) { - ret ures_err(terr_mismatch, expected, actual); - } + tag fn_common_res { + fn_common_res_err(unify_result); + fn_common_res_ok(vec[arg], @t); + } + fn unify_fn_common(@hashmap[int,@ty.t] bindings, + @ty.t expected, + @ty.t actual, + &unify_handler handler, + vec[arg] expected_inputs, @t expected_output, + vec[arg] actual_inputs, @t actual_output) + -> fn_common_res { auto expected_len = _vec.len[arg](expected_inputs); auto actual_len = _vec.len[arg](actual_inputs); if (expected_len != actual_len) { - ret ures_err(terr_arg_count, expected, actual); + ret fn_common_res_err(ures_err(terr_arg_count, + expected, actual)); } // TODO: as above, we should have an iter2 iterator. @@ -874,7 +884,7 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) } case (_) { - ret result; + ret fn_common_res_err(result); } } @@ -882,24 +892,67 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) } // Check the output. - auto result_out; auto result = unify_step(bindings, expected_output, actual_output, handler); alt (result) { case (ures_ok(?rty)) { - result_out = rty; + ret fn_common_res_ok(result_ins, rty); } case (_) { - ret result; + ret fn_common_res_err(result); } } + } - auto t = plain_ty(ty.ty_fn(e_proto, result_ins, result_out)); - ret ures_ok(t); + fn unify_fn(@hashmap[int,@ty.t] bindings, + ast.proto e_proto, + ast.proto a_proto, + @ty.t expected, + @ty.t actual, + &unify_handler handler, + vec[arg] expected_inputs, @t expected_output, + vec[arg] actual_inputs, @t actual_output) + -> unify_result { + if (e_proto != a_proto) { + ret ures_err(terr_mismatch, expected, actual); + } + auto t = unify_fn_common(bindings, expected, actual, + handler, expected_inputs, expected_output, + actual_inputs, actual_output); + alt (t) { + case (fn_common_res_err(?r)) { + ret r; + } + case (fn_common_res_ok(?result_ins, ?result_out)) { + auto t2 = plain_ty(ty.ty_fn(e_proto, result_ins, result_out)); + ret ures_ok(t2); + } + } + } + + fn unify_native_fn(@hashmap[int,@ty.t] bindings, + @ty.t expected, + @ty.t actual, + &unify_handler handler, + vec[arg] expected_inputs, @t expected_output, + vec[arg] actual_inputs, @t actual_output) + -> unify_result { + auto t = unify_fn_common(bindings, expected, actual, + handler, expected_inputs, expected_output, + actual_inputs, actual_output); + alt (t) { + case (fn_common_res_err(?r)) { + ret r; + } + case (fn_common_res_ok(?result_ins, ?result_out)) { + auto t2 = plain_ty(ty.ty_native_fn(result_ins, result_out)); + ret ures_ok(t2); + } + } } fn unify_obj(@hashmap[int,@ty.t] bindings, @@ -1258,6 +1311,20 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) } } + case (ty.ty_native_fn(?expected_inputs, ?expected_output)) { + alt (actual.struct) { + case (ty.ty_native_fn(?actual_inputs, ?actual_output)) { + ret unify_native_fn(bindings, + expected, actual, handler, + expected_inputs, expected_output, + actual_inputs, actual_output); + } + case (_) { + ret ures_err(terr_mismatch, expected, actual); + } + } + } + case (ty.ty_obj(?expected_meths)) { alt (actual.struct) { case (ty.ty_obj(?actual_meths)) { -- cgit v1.2.3 From b4d6589e7387a7c7df0841f51f0fa5ef831883d9 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 23 Feb 2011 10:58:43 -0800 Subject: Implement type descriptor binding. Un-XFAIL test/run-pass/generic-bind.rs. --- src/comp/middle/ty.rs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 0f277329..5535879e 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -598,12 +598,14 @@ fn ty_fn_args(@t fty) -> vec[arg] { case (ty.ty_fn(_, ?a, _)) { ret a; } case (ty.ty_native_fn(?a, _)) { ret a; } } + fail; } fn ty_fn_proto(@t fty) -> ast.proto { alt (fty.struct) { case (ty.ty_fn(?p, _, _)) { ret p; } } + fail; } fn ty_fn_ret(@t fty) -> @t { @@ -611,6 +613,7 @@ fn ty_fn_ret(@t fty) -> @t { case (ty.ty_fn(_, _, ?r)) { ret r; } case (ty.ty_native_fn(_, ?r)) { ret r; } } + fail; } fn is_fn_ty(@t fty) -> bool { -- cgit v1.2.3 From 19b2850388f634b500e612d8f24bbcb8c0fa2f3c Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 24 Feb 2011 19:24:12 -0800 Subject: rustc: Perform type parameter substitutions when emitting glue for generic tags. Un-XFAIL generic-tag.rs. --- src/comp/middle/ty.rs | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 5535879e..02a7ffc2 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -1450,7 +1450,7 @@ fn type_err_to_str(&ty.type_err err) -> str { } } -// Type parameter resolution, used in translation +// Type parameter resolution, used in translation and typechecking fn resolve_ty_params(ty_params_and_ty ty_params_and_polyty, @t monoty) -> vec[@t] { @@ -1492,6 +1492,47 @@ fn resolve_ty_params(ty_params_and_ty ty_params_and_polyty, ret result_tys; } +// Performs type parameter replacement using the supplied mapping from +// parameter IDs to types. +fn replace_type_params(@t typ, hashmap[ast.def_id,@t] param_map) -> @t { + state obj param_replacer(hashmap[ast.def_id,@t] param_map) { + fn fold_simple_ty(@t typ) -> @t { + alt (typ.struct) { + case (ty_param(?param_def)) { + if (param_map.contains_key(param_def)) { + ret param_map.get(param_def); + } else { + ret typ; + } + } + case (_) { + ret typ; + } + } + } + } + auto replacer = param_replacer(param_map); + ret fold_ty(replacer, typ); +} + +// Substitutes the type parameters specified by @ty_params with the +// corresponding types in @bound in the given type. The two vectors must have +// the same length. +fn substitute_ty_params(vec[ast.ty_param] ty_params, vec[@t] bound, @t ty) + -> @t { + auto ty_param_len = _vec.len[ast.ty_param](ty_params); + check (ty_param_len == _vec.len[@t](bound)); + + auto bindings = common.new_def_hash[@t](); + auto i = 0u; + while (i < ty_param_len) { + bindings.insert(ty_params.(i).id, bound.(i)); + i += 1u; + } + + ret replace_type_params(ty, bindings); +} + // Local Variables: // mode: rust // fill-column: 78; -- cgit v1.2.3 From 081c3aa76dd0805767e0233c0cc6ccf313cf44ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20=C3=81vila=20de=20Esp=C3=ADndola?= Date: Fri, 25 Feb 2011 15:58:08 -0500 Subject: Pass the abi of native functions all the way to codegen. --- src/comp/middle/ty.rs | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 02a7ffc2..f19c2997 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -41,7 +41,7 @@ tag sty { ty_tup(vec[@t]); ty_rec(vec[field]); ty_fn(ast.proto, vec[arg], @t); // TODO: effect - ty_native_fn(vec[arg], @t); // TODO: effect + ty_native_fn(ast.native_abi, vec[arg], @t); // TODO: effect ty_obj(vec[method]); ty_var(int); // ephemeral type var ty_local(ast.def_id); // type of a local var @@ -261,7 +261,7 @@ fn ty_to_str(&@t typ) -> str { s = fn_to_str(proto, none[ast.ident], inputs, output); } - case (ty_native_fn(?inputs, ?output)) { + case (ty_native_fn(_, ?inputs, ?output)) { s = fn_to_str(ast.proto_fn, none[ast.ident], inputs, output); } @@ -346,13 +346,13 @@ fn fold_ty(ty_fold fld, @t ty) -> @t { } ret rewrap(ty, ty_fn(proto, new_args, fold_ty(fld, ret_ty))); } - case (ty_native_fn(?args, ?ret_ty)) { + case (ty_native_fn(?abi, ?args, ?ret_ty)) { let vec[arg] new_args = vec(); for (arg a in args) { auto new_ty = fold_ty(fld, a.ty); new_args += vec(rec(mode=a.mode, ty=new_ty)); } - ret rewrap(ty, ty_native_fn(new_args, fold_ty(fld, ret_ty))); + ret rewrap(ty, ty_native_fn(abi, new_args, fold_ty(fld, ret_ty))); } case (ty_obj(?methods)) { let vec[method] new_methods = vec(); @@ -596,7 +596,7 @@ fn count_ty_params(@t ty) -> uint { fn ty_fn_args(@t fty) -> vec[arg] { alt (fty.struct) { case (ty.ty_fn(_, ?a, _)) { ret a; } - case (ty.ty_native_fn(?a, _)) { ret a; } + case (ty.ty_native_fn(_, ?a, _)) { ret a; } } fail; } @@ -611,7 +611,7 @@ fn ty_fn_proto(@t fty) -> ast.proto { fn ty_fn_ret(@t fty) -> @t { alt (fty.struct) { case (ty.ty_fn(_, _, ?r)) { ret r; } - case (ty.ty_native_fn(_, ?r)) { ret r; } + case (ty.ty_native_fn(_, _, ?r)) { ret r; } } fail; } @@ -619,7 +619,7 @@ fn ty_fn_ret(@t fty) -> @t { fn is_fn_ty(@t fty) -> bool { alt (fty.struct) { case (ty.ty_fn(_, _, _)) { ret true; } - case (ty.ty_native_fn(_, _)) { ret true; } + case (ty.ty_native_fn(_, _, _)) { ret true; } case (_) { ret false; } } ret false; @@ -938,12 +938,18 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) } fn unify_native_fn(@hashmap[int,@ty.t] bindings, + ast.native_abi e_abi, + ast.native_abi a_abi, @ty.t expected, @ty.t actual, &unify_handler handler, vec[arg] expected_inputs, @t expected_output, vec[arg] actual_inputs, @t actual_output) -> unify_result { + if (e_abi != a_abi) { + ret ures_err(terr_mismatch, expected, actual); + } + auto t = unify_fn_common(bindings, expected, actual, handler, expected_inputs, expected_output, actual_inputs, actual_output); @@ -952,7 +958,8 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) ret r; } case (fn_common_res_ok(?result_ins, ?result_out)) { - auto t2 = plain_ty(ty.ty_native_fn(result_ins, result_out)); + auto t2 = plain_ty(ty.ty_native_fn(e_abi, result_ins, + result_out)); ret ures_ok(t2); } } @@ -1314,10 +1321,12 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) } } - case (ty.ty_native_fn(?expected_inputs, ?expected_output)) { + case (ty.ty_native_fn(?e_abi, ?expected_inputs, + ?expected_output)) { alt (actual.struct) { - case (ty.ty_native_fn(?actual_inputs, ?actual_output)) { - ret unify_native_fn(bindings, + case (ty.ty_native_fn(?a_abi, ?actual_inputs, + ?actual_output)) { + ret unify_native_fn(bindings, e_abi, a_abi, expected, actual, handler, expected_inputs, expected_output, actual_inputs, actual_output); -- cgit v1.2.3 From 0120571e90a68befb03892c63c470d0923d425c4 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 25 Feb 2011 19:42:26 -0800 Subject: rustc: Make the tag info table keyed by both tag ID and type parameter. Also fix a bug that was causing all tags to compare equal. --- src/comp/middle/ty.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index f19c2997..25ef8709 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -247,9 +247,10 @@ fn ty_to_str(&@t typ) -> str { s = "rec(" + _str.connect(strs, ",") + ")"; } - case (ty_tag(_, ?tps)) { + case (ty_tag(?id, ?tps)) { // The user should never see this if the cname is set properly! - s = ""; + s = ""; if (_vec.len[@t](tps) > 0u) { auto f = ty_to_str; auto strs = _vec.map[@t,str](f, tps); -- cgit v1.2.3 From 8d8b3d985a02153a349e72bd9840231b43c51864 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 28 Feb 2011 19:07:26 -0800 Subject: rustc: Mark tags that have subtypes with dynamic size as dynamic --- src/comp/middle/ty.rs | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 25ef8709..8b9ef6d1 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -471,6 +471,13 @@ fn type_has_dynamic_size(@t ty) -> bool { i += 1u; } } + case (ty_tag(_, ?subtys)) { + auto i = 0u; + while (i < _vec.len[@t](subtys)) { + if (type_has_dynamic_size(subtys.(i))) { ret true; } + i += 1u; + } + } case (ty_param(_)) { ret true; } case (_) { /* fall through */ } } -- cgit v1.2.3 From f1500e5872d03e3ec3b140060641136a2ff5a15a Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 26 Feb 2011 20:51:02 -0500 Subject: Add fold, typecheck and trans for expr_ext --- src/comp/middle/ty.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 8b9ef6d1..478f54d1 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -749,6 +749,7 @@ fn expr_ty(@ast.expr expr) -> @t { case (ast.expr_field(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_index(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_path(_, _, ?ann)) { ret ann_to_type(ann); } + case (ast.expr_ext(_, _, _, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_fail) { ret plain_ty(ty_nil); } case (ast.expr_log(_)) { ret plain_ty(ty_nil); } -- cgit v1.2.3 From dddeba19d33a1aa2e7681ae84424dbe4d7b510b7 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Wed, 2 Mar 2011 16:42:09 -0800 Subject: Sketch out some more pieces of vec-append. --- src/comp/middle/ty.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 478f54d1..771136da 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -395,6 +395,7 @@ fn type_is_nil(@t ty) -> bool { fail; } + fn type_is_structural(@t ty) -> bool { alt (ty.struct) { case (ty_tup(_)) { ret true; } @@ -407,6 +408,15 @@ fn type_is_structural(@t ty) -> bool { fail; } +fn type_is_sequence(@t ty) -> bool { + alt (ty.struct) { + case (ty_str) { ret true; } + case (ty_vec(_)) { ret true; } + case (_) { ret false; } + } + fail; +} + fn type_is_tup_like(@t ty) -> bool { alt (ty.struct) { case (ty_box(_)) { ret true; } -- cgit v1.2.3 From da8058ff836a4e9a30e36ef96449dfef576b13e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20=C3=81vila=20de=20Esp=C3=ADndola?= Date: Thu, 3 Mar 2011 16:43:47 -0500 Subject: Handle native types in calls. --- src/comp/middle/ty.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 771136da..c85892f2 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -465,6 +465,16 @@ fn type_is_scalar(@t ty) -> bool { fail; } +// FIXME: should we just return true for native types in +// type_is_scalar? +fn type_is_native(@t ty) -> bool { + alt (ty.struct) { + case (ty_native) { ret true; } + case (_) { ret false; } + } + fail; +} + fn type_has_dynamic_size(@t ty) -> bool { alt (ty.struct) { case (ty_tup(?ts)) { -- cgit v1.2.3 From f6682280f3e3e8923c283df8277964b6cbf8d8b8 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 3 Mar 2011 16:54:15 -0800 Subject: rustc: Add support for folding over tag types --- src/comp/middle/ty.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index c85892f2..a44cdb4d 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -294,6 +294,7 @@ fn ty_to_str(&@t typ) -> str { type ty_fold = state obj { fn fold_simple_ty(@t ty) -> @t; + fn fold_tag_ty(@t ty) -> @t; }; fn fold_ty(ty_fold fld, @t ty) -> @t { @@ -322,7 +323,8 @@ fn fold_ty(ty_fold fld, @t ty) -> @t { for (@t subty in subtys) { new_subtys += vec(fold_ty(fld, subty)); } - ret rewrap(ty, ty_tag(tid, new_subtys)); + auto typ = rewrap(ty, ty_tag(tid, new_subtys)); + ret fld.fold_tag_ty(typ); } case (ty_tup(?subtys)) { let vec[@t] new_subtys = vec(); @@ -611,6 +613,8 @@ fn count_ty_params(@t ty) -> uint { } ret ty; } + + fn fold_tag_ty(@t ty) -> @t { ret ty; } } let vec[ast.def_id] param_ids_inner = vec(); @@ -1429,6 +1433,8 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) } } } + + fn fold_tag_ty(@t typ) -> @t { ret typ; } } ret ty.fold_ty(folder(bindings), typ); @@ -1548,6 +1554,8 @@ fn replace_type_params(@t typ, hashmap[ast.def_id,@t] param_map) -> @t { } } } + + fn fold_tag_ty(@t typ) -> @t { ret typ; } } auto replacer = param_replacer(param_map); ret fold_ty(replacer, typ); -- cgit v1.2.3 From 04a0a6fbef0cc7c3c89fbbbeff68ab2c999d9592 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 3 Mar 2011 17:09:20 -0800 Subject: Revert "rustc: Add support for folding over tag types" as it's unnecessary. Oops. --- src/comp/middle/ty.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index a44cdb4d..c85892f2 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -294,7 +294,6 @@ fn ty_to_str(&@t typ) -> str { type ty_fold = state obj { fn fold_simple_ty(@t ty) -> @t; - fn fold_tag_ty(@t ty) -> @t; }; fn fold_ty(ty_fold fld, @t ty) -> @t { @@ -323,8 +322,7 @@ fn fold_ty(ty_fold fld, @t ty) -> @t { for (@t subty in subtys) { new_subtys += vec(fold_ty(fld, subty)); } - auto typ = rewrap(ty, ty_tag(tid, new_subtys)); - ret fld.fold_tag_ty(typ); + ret rewrap(ty, ty_tag(tid, new_subtys)); } case (ty_tup(?subtys)) { let vec[@t] new_subtys = vec(); @@ -613,8 +611,6 @@ fn count_ty_params(@t ty) -> uint { } ret ty; } - - fn fold_tag_ty(@t ty) -> @t { ret ty; } } let vec[ast.def_id] param_ids_inner = vec(); @@ -1433,8 +1429,6 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) } } } - - fn fold_tag_ty(@t typ) -> @t { ret typ; } } ret ty.fold_ty(folder(bindings), typ); @@ -1554,8 +1548,6 @@ fn replace_type_params(@t typ, hashmap[ast.def_id,@t] param_map) -> @t { } } } - - fn fold_tag_ty(@t typ) -> @t { ret typ; } } auto replacer = param_replacer(param_map); ret fold_ty(replacer, typ); -- cgit v1.2.3 From 652cb484758a72811e16a574805ce60827daa153 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Thu, 3 Mar 2011 18:18:51 -0800 Subject: Assortment of additional work on vec-append. Not done yet. --- src/comp/middle/ty.rs | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index c85892f2..2fc3160c 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -417,6 +417,15 @@ fn type_is_sequence(@t ty) -> bool { fail; } +fn sequence_element_type(@t ty) -> @t { + alt (ty.struct) { + case (ty_str) { ret plain_ty(ty_machine(common.ty_u8)); } + case (ty_vec(?e)) { ret e; } + } + fail; +} + + fn type_is_tup_like(@t ty) -> bool { alt (ty.struct) { case (ty_box(_)) { ret true; } -- cgit v1.2.3 From d97c800e3179604db82e35bff682ea1ed6ec3909 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Sat, 5 Mar 2011 20:05:02 +0000 Subject: Make ret and fail stmts have 0 out-edges, Closes #250. --- src/comp/middle/ty.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 2fc3160c..0b6ef53b 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -373,7 +373,7 @@ fn fold_ty(ty_fold fld, @t ty) -> @t { case (ty_param(_)) { ret fld.fold_simple_ty(ty); } } - ret ty; + fail; } // Type utilities -- cgit v1.2.3 From d39da6f97819becd9ea41c194b5f0daa178814fe Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 6 Mar 2011 13:56:38 -0500 Subject: Remove typestate workarounds --- src/comp/middle/ty.rs | 42 +++++++++++++----------------------------- 1 file changed, 13 insertions(+), 29 deletions(-) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 0b6ef53b..3f209d3c 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -1018,32 +1018,6 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) ret ures_err(terr_meth_count, expected, actual); } - // FIXME: work around buggy typestate logic for 'alt', sigh. - fn is_ok(&unify_result r) -> bool { - alt (r) { - case (ures_ok(?tfn)) { - ret true; - } - case (_) {} - } - ret false; - } - - fn append_if_ok(&method e_meth, - &unify_result r, &mutable vec[method] result_meths) { - alt (r) { - case (ures_ok(?tfn)) { - alt (tfn.struct) { - case (ty_fn(?proto, ?ins, ?out)) { - result_meths += vec(rec(inputs = ins, - output = out - with e_meth)); - } - } - } - } - } - while (i < expected_len) { auto e_meth = expected_meths.(i); auto a_meth = actual_meths.(i); @@ -1056,10 +1030,20 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) expected, actual, handler, e_meth.inputs, e_meth.output, a_meth.inputs, a_meth.output); - if (!is_ok(r)) { - ret r; + alt (r) { + case (ures_ok(?tfn)) { + alt (tfn.struct) { + case (ty_fn(?proto, ?ins, ?out)) { + result_meths += vec(rec(inputs = ins, + output = out + with e_meth)); + } + } + } + case (_) { + ret r; + } } - append_if_ok(e_meth, r, result_meths); i += 1u; } auto t = plain_ty(ty_obj(result_meths)); -- cgit v1.2.3 From 8047957b9981c4f3539ba3d307a65e0255477e81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20=C3=81vila=20de=20Esp=C3=ADndola?= Date: Mon, 7 Mar 2011 15:37:40 -0500 Subject: Construct the wrappers to native functions. Hello world now works :-) --- src/comp/middle/ty.rs | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 3f209d3c..62d9a2f0 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -645,6 +645,13 @@ fn ty_fn_proto(@t fty) -> ast.proto { fail; } +fn ty_fn_abi(@t fty) -> ast.native_abi { + alt (fty.struct) { + case (ty.ty_native_fn(?a, _, _)) { ret a; } + } + fail; +} + fn ty_fn_ret(@t fty) -> @t { alt (fty.struct) { case (ty.ty_fn(_, _, ?r)) { ret r; } -- cgit v1.2.3 From 0624f9db4aeaa5681941750c3a1a17ca5fbb7e72 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 4 Mar 2011 07:22:43 +0100 Subject: Add a pretty-printer Adds a -pp option to the compiler which will cause it to simply pretty-print the given file. --- src/comp/middle/ty.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/comp/middle/ty.rs') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 62d9a2f0..c33b5d8d 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -169,6 +169,8 @@ fn path_to_str(&ast.path pth) -> str { ret result; } +// FIXME use the pretty-printer for this once it has a concept of an +// abstract stream fn ty_to_str(&@t typ) -> str { fn fn_input_to_str(&rec(ast.mode mode, @t ty) input) -> str { -- cgit v1.2.3