aboutsummaryrefslogtreecommitdiff
path: root/src/comp
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2010-12-30 15:28:19 -0800
committerGraydon Hoare <[email protected]>2010-12-30 15:28:19 -0800
commit153efb58bc1a50d12997081a0cbb0db19c12103b (patch)
tree5a6b5a643367b0acdaca1a053427b71a0218f6fc /src/comp
parentTeach resolve to find obj fields and ty params from methods. (diff)
downloadrust-153efb58bc1a50d12997081a0cbb0db19c12103b.tar.xz
rust-153efb58bc1a50d12997081a0cbb0db19c12103b.zip
Teach typeck to check obj field accesses.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/typeck.rs44
1 files changed, 41 insertions, 3 deletions
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index c4fd7d7f..b5cc5e76 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -33,6 +33,7 @@ import std.option.some;
type ty_table = hashmap[ast.def_id, @ty.t];
type crate_ctxt = rec(session.session sess,
@ty_table item_types,
+ vec[ast.obj_field] obj_fields,
mutable int next_var_id);
type fn_ctxt = rec(@ty.t ret_ty,
@@ -410,6 +411,7 @@ fn collect_item_types(@ast.crate crate) -> tup(@ast.crate, @ty_table) {
auto t = e.item_to_ty.get(id);
let vec[method] meth_tys = get_ctor_obj_methods(t);
let vec[@ast.method] methods = vec();
+ let vec[ast.obj_field] fields = vec();
let uint n = 0u;
for (method meth_ty in meth_tys) {
@@ -423,8 +425,16 @@ fn collect_item_types(@ast.crate crate) -> tup(@ast.crate, @ty_table) {
append[@ast.method](methods, m);
n += 1u;
}
+ auto g = bind getter(e.id_to_ty_item, e.item_to_ty, _);
+ for (ast.obj_field fld in ob.fields) {
+ let @ty.t fty = ast_ty_to_ty(g, fld.ty);
+ let ast.obj_field f = rec(ann=ast.ann_type(fty) with fld);
+ append[ast.obj_field](fields, f);
+ }
- auto ob_ = rec(methods = methods with ob);
+ auto ob_ = rec(methods = methods,
+ fields = fields
+ with ob);
auto item = ast.item_obj(i, ob_, ty_params, id,
ast.ann_type(t));
ret @fold.respan[ast.item_](sp, item);
@@ -915,6 +925,10 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
case (none[@ty.t]) { t = plain_ty(ty.ty_local(id)); }
}
}
+ case (ast.def_obj_field(?id)) {
+ check (fcx.locals.contains_key(id));
+ t = fcx.locals.get(id);
+ }
case (ast.def_fn(?id)) {
check (fcx.ccx.item_types.contains_key(id));
t = generalize_ty(fcx.ccx, fcx.ccx.item_types.get(id));
@@ -1456,11 +1470,18 @@ fn check_fn(&@crate_ctxt ccx, ast.effect effect,
// and return type translated to typeck.ty values. We don't need do to it
// again here, we can extract them.
+
+ for (ast.obj_field f in ccx.obj_fields) {
+ auto field_ty = ty.ann_to_type(f.ann);
+ local_ty_table.insert(f.id, field_ty);
+ }
+
// Store the type of each argument in the table.
for (ast.arg arg in inputs) {
auto input_ty = ast_ty_to_ty_crate(ccx, arg.ty);
local_ty_table.insert(arg.id, input_ty);
}
+
let @fn_ctxt fcx = @rec(ret_ty = ast_ty_to_ty_crate(ccx, output),
locals = local_ty_table,
ccx = ccx);
@@ -1496,14 +1517,31 @@ fn check_item_fn(&@crate_ctxt ccx, &span sp, ast.ident ident, &ast._fn f,
ret @fold.respan[ast.item_](sp, item);
}
+fn update_obj_fields(&@crate_ctxt ccx, @ast.item i) -> @crate_ctxt {
+ alt (i.node) {
+ case (ast.item_obj(_, ?ob, _, _, _)) {
+ ret @rec(obj_fields = ob.fields with *ccx);
+ }
+ case (_) {
+ }
+ }
+ ret ccx;
+}
+
fn check_crate(session.session sess, @ast.crate crate) -> @ast.crate {
auto result = collect_item_types(crate);
- auto ccx = @rec(sess=sess, item_types=result._1, mutable next_var_id=0);
+ let vec[ast.obj_field] fields = vec();
+
+ auto ccx = @rec(sess=sess,
+ item_types=result._1,
+ obj_fields=fields,
+ mutable next_var_id=0);
auto fld = fold.new_identity_fold[@crate_ctxt]();
- fld = @rec(fold_fn = bind check_fn(_,_,_,_,_),
+ fld = @rec(update_env_for_item = bind update_obj_fields(_, _),
+ fold_fn = bind check_fn(_,_,_,_,_),
fold_item_fn = bind check_item_fn(_,_,_,_,_,_,_)
with *fld);
ret fold.fold_crate[@crate_ctxt](ccx, fld, result._0);