diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index c3b0e68754537..6dd229fbbb6cc 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))); } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 5b14eea4101c6..d524e8ae177b1 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -31,7 +31,13 @@ import std.option.none; import std.option.some; type ty_table = hashmap[ast.def_id, @ty.t]; -type ty_item_table = hashmap[ast.def_id,@ast.item]; + +tag any_item { + any_item_rust(@ast.item); + any_item_native(@ast.native_item); +} + +type ty_item_table = hashmap[ast.def_id,any_item]; type crate_ctxt = rec(session.session sess, @ty_table item_types, @@ -161,6 +167,9 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t { case (ast.def_ty(?id)) { sty = instantiate(getter, id, path.node.types).struct; } + case (ast.def_native_ty(?id)) { + sty = instantiate(getter, id, path.node.types).struct; + } case (ast.def_obj(?id)) { sty = instantiate(getter, id, path.node.types).struct; } @@ -196,23 +205,36 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t { ret @rec(struct=sty, mut=mut, cname=cname); } +fn actual_type(@ty.t t, @ast.item item) -> @ty.t { + alt (item.node) { + case (ast.item_obj(_,_,_,_,_)) { + // An obj used as a type name refers to the output type of the + // item (constructor). + ret middle.ty.ty_fn_ret(t); + } + case (_) { } + } + + ret t; +} + // A convenience function to use a crate_ctxt to resolve names for // 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_items.contains_key(id)); check (ccx.item_types.contains_key(id)); - auto item = ccx.item_items.get(id); + auto it = 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); + auto params; + alt (it) { + case (any_item_rust(?item)) { + ty = actual_type(ty, item); + params = ty_params_of_item(item); } - case (_) { } + case (any_item_native(?native_item)) { + params = ty_params_of_native_item(native_item); + } } ret rec(params = params, ty = ty); @@ -242,6 +264,18 @@ fn ty_params_of_item(@ast.item item) -> vec[ast.ty_param] { } } +fn ty_params_of_native_item(@ast.native_item item) -> vec[ast.ty_param] { + alt (item.node) { + case (ast.native_item_fn(_, _, ?p, _)) { + ret p; + } + case (_) { + let vec[ast.ty_param] r = vec(); + ret r; + } + } +} + // Item collection - a pair of bootstrap passes: // // 1. Collect the IDs of all type items (typedefs) and store them in a table. @@ -253,6 +287,19 @@ fn ty_params_of_item(@ast.item item) -> vec[ast.ty_param] { // We then annotate the AST with the resulting types and return the annotated // AST, along with a table mapping item IDs to their types. +fn ty_of_fn_decl(@ty_item_table id_to_ty_item, + @ty_table item_to_ty, + fn(&@ast.ty ast_ty) -> @ty.t convert, + fn(&ast.arg a) -> arg ty_of_arg, + &ast.fn_decl decl, + ast.def_id def_id) -> @ty.t { + auto input_tys = _vec.map[ast.arg,arg](ty_of_arg, decl.inputs); + auto output_ty = convert(decl.output); + auto t_fn = plain_ty(ty.ty_fn(input_tys, output_ty)); + item_to_ty.insert(def_id, t_fn); + ret t_fn; +} + fn collect_item_types(session.session sess, @ast.crate crate) -> tup(@ast.crate, @ty_table, @ty_item_table) { @@ -260,17 +307,20 @@ fn collect_item_types(session.session sess, @ast.crate crate) @ty_table item_to_ty, ast.def_id id) -> ty_and_params { check (id_to_ty_item.contains_key(id)); - 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); + auto it = id_to_ty_item.get(id); + auto ty; + auto params; + alt (it) { + case (any_item_rust(?item)) { + ty = ty_of_item(id_to_ty_item, item_to_ty, item); + ty = actual_type(ty, item); + params = ty_params_of_item(item); + } + case (any_item_native(?native_item)) { + ty = ty_of_native_item(id_to_ty_item, item_to_ty, + native_item); + params = ty_params_of_native_item(native_item); } - case (_) { } } ret rec(params = params, ty = ty); @@ -340,16 +390,9 @@ fn collect_item_types(session.session sess, @ast.crate crate) } case (ast.item_fn(?ident, ?fn_info, _, ?def_id, _)) { - // TODO: handle ty-params - auto f = bind ty_of_arg(id_to_ty_item, item_to_ty, _); - auto input_tys = _vec.map[ast.arg,arg](f, - fn_info.decl.inputs); - auto output_ty = convert(fn_info.decl.output); - - auto t_fn = plain_ty(ty.ty_fn(input_tys, output_ty)); - item_to_ty.insert(def_id, t_fn); - ret t_fn; + ret ty_of_fn_decl(id_to_ty_item, item_to_ty, convert, f, + fn_info.decl, def_id); } case (ast.item_obj(?ident, ?obj_info, _, ?def_id, _)) { @@ -385,6 +428,30 @@ fn collect_item_types(session.session sess, @ast.crate crate) } } + fn ty_of_native_item(@ty_item_table id_to_ty_item, + @ty_table item_to_ty, + @ast.native_item it) -> @ty.t { + alt (it.node) { + case (ast.native_item_fn(?ident, ?fn_decl, ?params, ?def_id)) { + auto get = bind getter(id_to_ty_item, item_to_ty, _); + auto convert = bind ast_ty_to_ty(get, _); + auto f = bind ty_of_arg(id_to_ty_item, item_to_ty, _); + ret ty_of_fn_decl(id_to_ty_item, item_to_ty, convert, f, + fn_decl, def_id); + } + case (ast.native_item_ty(_, ?def_id)) { + if (item_to_ty.contains_key(def_id)) { + // Avoid repeating work. + ret item_to_ty.get(def_id); + } + auto x = + @rec(struct=ty.ty_native, mut=ast.imm, cname=none[str]); + item_to_ty.insert(def_id, x); + ret x; + } + } + } + fn get_tag_variant_types(@ty_item_table id_to_ty_item, @ty_table item_to_ty, &ast.def_id tag_id, @@ -422,25 +489,38 @@ fn collect_item_types(session.session sess, @ast.crate crate) // First pass: collect all type item IDs. auto module = crate.node.module; - auto id_to_ty_item = @common.new_def_hash[@ast.item](); + auto id_to_ty_item = @common.new_def_hash[any_item](); fn collect(&@ty_item_table id_to_ty_item, @ast.item i) -> @ty_item_table { alt (i.node) { case (ast.item_ty(_, _, _, ?def_id, _)) { - id_to_ty_item.insert(def_id, i); + id_to_ty_item.insert(def_id, any_item_rust(i)); } case (ast.item_tag(_, _, _, ?def_id)) { - id_to_ty_item.insert(def_id, i); + id_to_ty_item.insert(def_id, any_item_rust(i)); } case (ast.item_obj(_, _, _, ?def_id, _)) { - id_to_ty_item.insert(def_id, i); + id_to_ty_item.insert(def_id, any_item_rust(i)); } case (_) { /* empty */ } } ret id_to_ty_item; } + fn collect_native(&@ty_item_table id_to_ty_item, @ast.native_item i) + -> @ty_item_table { + alt (i.node) { + case (ast.native_item_ty(_, ?def_id)) { + id_to_ty_item.insert(def_id, any_item_native(i)); + } + case (ast.native_item_fn(_, _, _, ?def_id)) { + id_to_ty_item.insert(def_id, any_item_native(i)); + } + } + ret id_to_ty_item; + } auto fld_1 = fold.new_identity_fold[@ty_item_table](); - fld_1 = @rec(update_env_for_item = bind collect(_, _) + fld_1 = @rec(update_env_for_item = bind collect(_, _), + update_env_for_native_item = bind collect_native(_, _) with *fld_1); fold.fold_crate[@ty_item_table](id_to_ty_item, fld_1, crate); @@ -473,6 +553,11 @@ fn collect_item_types(session.session sess, @ast.crate crate) ret e; } + fn convert_native(&@env e, @ast.native_item i) -> @env { + ty_of_native_item(e.id_to_ty_item, e.item_to_ty, i); + ret e; + } + fn fold_item_const(&@env e, &span sp, ast.ident i, @ast.ty t, @ast.expr ex, ast.def_id id, ast.ann a) -> @ast.item { @@ -575,6 +660,7 @@ fn collect_item_types(session.session sess, @ast.crate crate) auto fld_2 = fold.new_identity_fold[@env](); fld_2 = @rec(update_env_for_item = bind convert(_,_), + update_env_for_native_item = bind convert_native(_,_), fold_item_const = bind fold_item_const(_,_,_,_,_,_,_), fold_item_fn = bind fold_item_fn(_,_,_,_,_,_,_), fold_item_obj = bind fold_item_obj(_,_,_,_,_,_,_), @@ -1150,6 +1236,10 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr { check (fcx.ccx.item_types.contains_key(id)); t = generalize_ty(fcx.ccx, fcx.ccx.item_types.get(id)); } + case (ast.def_native_fn(?id)) { + check (fcx.ccx.item_types.contains_key(id)); + t = generalize_ty(fcx.ccx, fcx.ccx.item_types.get(id)); + } case (ast.def_const(?id)) { check (fcx.ccx.item_types.contains_key(id)); t = fcx.ccx.item_types.get(id);