diff options
| author | Graydon Hoare <[email protected]> | 2011-01-26 11:35:30 -0800 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2011-01-26 11:35:30 -0800 |
| commit | 596a97cf70b5329fb6bfe779ab1425a0e37a61d2 (patch) | |
| tree | 00bbb948db05f0246ac06627cbea8d4e10644f56 | |
| parent | Fix test now that we look at the full error-pattern. Also enable it for rustc. (diff) | |
| download | rust-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.rs | 65 |
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; |