提交 0d27eb13 编写于 作者: R Rafael Avila de Espindola 提交者: Graydon Hoare

Add type checking for native types.

上级 2b669008
......@@ -43,6 +43,7 @@
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 rewrap(@t orig, &sty new) -> @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)));
}
......
......@@ -31,7 +31,13 @@
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 instantiate(ty_getter getter, ast.def_id id,
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 instantiate(ty_getter getter, ast.def_id id,
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 getter(@ty_item_table id_to_ty_item,
@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 ty_of_item(@ty_item_table id_to_ty_item,
}
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 ty_of_item(@ty_item_table id_to_ty_item,
}
}
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 get_tag_variant_types(@ty_item_table id_to_ty_item,
// 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 convert(&@env e, @ast.item i) -> @env {
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 fold_item_tag(&@env e, &span sp, ast.ident i,
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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册