aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2011-01-26 11:35:30 -0800
committerGraydon Hoare <[email protected]>2011-01-26 11:35:30 -0800
commit596a97cf70b5329fb6bfe779ab1425a0e37a61d2 (patch)
tree00bbb948db05f0246ac06627cbea8d4e10644f56
parentFix test now that we look at the full error-pattern. Also enable it for rustc. (diff)
downloadrust-596a97cf70b5329fb6bfe779ab1425a0e37a61d2.tar.xz
rust-596a97cf70b5329fb6bfe779ab1425a0e37a61d2.zip
Teach typeck to handle obj item names when used as type names, not just constructor calls.
-rw-r--r--src/comp/middle/typeck.rs65
1 files changed, 47 insertions, 18 deletions
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index 98fcc0d4..e21e72a9 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -98,6 +98,24 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t {
ret ty.fold_ty(replacer, t);
}
+ fn instantiate(ty_getter getter, ast.def_id id,
+ vec[@ast.ty] args) -> @ty.t {
+ // TODO: maybe record cname chains so we can do
+ // "foo = int" like OCaml?
+ auto ty_and_params = getter(id);
+ auto params = ty_and_params.params;
+ auto num_type_args = _vec.len[@ast.ty](args);
+ check(num_type_args == _vec.len[ast.ty_param](params));
+
+ auto param_map = common.new_def_hash[@ty.t]();
+ for each (uint i in _uint.range(0u, num_type_args)) {
+ auto arg = args.(i);
+ auto param = params.(i);
+ param_map.insert(param.id, ast_ty_to_ty(getter, arg));
+ }
+ ret replace_type_params(ty_and_params.ty, param_map);
+ }
+
auto mut = ast.imm;
auto sty;
auto cname = none[str];
@@ -137,22 +155,10 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t {
check (def != none[ast.def]);
alt (option.get[ast.def](def)) {
case (ast.def_ty(?id)) {
- // TODO: maybe record cname chains so we can do
- // "foo = int" like OCaml?
- auto ty_and_params = getter(id);
- auto params = ty_and_params.params;
- auto num_type_params = _vec.len[@ast.ty](path.node.types);
- check(num_type_params == _vec.len[ast.ty_param](params));
-
- auto param_map = common.new_def_hash[@ty.t]();
- for each (uint i in _uint.range(0u, num_type_params)) {
- auto x = path.node.types.(i);
- auto y = params.(i);
- param_map.insert(y.id, ast_ty_to_ty(getter, x));
- }
-
- sty = replace_type_params(ty_and_params.ty,
- param_map).struct;
+ sty = instantiate(getter, id, path.node.types).struct;
+ }
+ case (ast.def_obj(?id)) {
+ sty = instantiate(getter, id, path.node.types).struct;
}
case (ast.def_ty_arg(?id)) { sty = ty.ty_param(id); }
case (_) { fail; }
@@ -190,11 +196,21 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t {
// ast_ty_to_ty.
fn ast_ty_to_ty_crate(@crate_ctxt ccx, &@ast.ty ast_ty) -> @ty.t {
fn getter(@crate_ctxt ccx, ast.def_id id) -> ty_and_params {
- check (ccx.item_types.contains_key(id));
check (ccx.item_items.contains_key(id));
- auto ty = ccx.item_types.get(id);
+ check (ccx.item_types.contains_key(id));
auto item = ccx.item_items.get(id);
+ auto ty = ccx.item_types.get(id);
auto params = ty_params_of_item(item);
+
+ alt (item.node) {
+ case (ast.item_obj(_,_,_,_,_)) {
+ // An obj used as a type name refers to the output type of the
+ // item (constructor).
+ ty = middle.ty.ty_fn_ret(ty);
+ }
+ case (_) { }
+ }
+
ret rec(params = params, ty = ty);
}
auto f = bind getter(ccx, _);
@@ -243,6 +259,16 @@ fn collect_item_types(session.session sess, @ast.crate crate)
auto item = id_to_ty_item.get(id);
auto ty = ty_of_item(id_to_ty_item, item_to_ty, item);
auto params = ty_params_of_item(item);
+
+ alt (item.node) {
+ case (ast.item_obj(_,_,_,_,_)) {
+ // An obj used as a type name refers to the output type of the
+ // item (constructor).
+ ty = middle.ty.ty_fn_ret(ty);
+ }
+ case (_) { }
+ }
+
ret rec(params = params, ty = ty);
}
@@ -400,6 +426,9 @@ fn collect_item_types(session.session sess, @ast.crate crate)
case (ast.item_tag(_, _, _, ?def_id)) {
id_to_ty_item.insert(def_id, i);
}
+ case (ast.item_obj(_, _, _, ?def_id, _)) {
+ id_to_ty_item.insert(def_id, i);
+ }
case (_) { /* empty */ }
}
ret id_to_ty_item;