aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2010-12-15 20:23:36 -0800
committerGraydon Hoare <[email protected]>2010-12-15 20:23:36 -0800
commitd8d2220b30103a1819148944fb5c04de68dfd93e (patch)
tree04a49877d404ca0ca51fc34332da5e204de8104e /src
parentConvert obj item type to ctor type rather than obj type. (diff)
downloadrust-d8d2220b30103a1819148944fb5c04de68dfd93e.tar.xz
rust-d8d2220b30103a1819148944fb5c04de68dfd93e.zip
Typecheck object method calls.
Diffstat (limited to 'src')
-rw-r--r--src/comp/middle/typeck.rs30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index b58b874f..bd12cf6f 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -673,6 +673,19 @@ fn field_idx(session.session sess, &span sp,
fail;
}
+fn method_idx(session.session sess, &span sp,
+ &ast.ident id, vec[method] meths) -> uint {
+ let uint i = 0u;
+ for (method m in meths) {
+ if (_str.eq(m.ident, id)) {
+ ret i;
+ }
+ i += 1u;
+ }
+ sess.span_err(sp, "unknown method '" + id + "' of obj");
+ fail;
+}
+
fn is_lval(@ast.expr expr) -> bool {
alt (expr.node) {
case (ast.expr_field(_,_,_)) { ret true; }
@@ -1830,6 +1843,7 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
}
case (ast.expr_call(?f, ?args, _)) {
+
// Check the function.
auto f_0 = check_expr(fcx, f);
@@ -1994,6 +2008,22 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
ann));
}
+ case (ty_obj(?methods)) {
+ let uint ix = method_idx(fcx.ccx.sess,
+ expr.span, field, methods);
+ if (ix >= _vec.len[typeck.method](methods)) {
+ fcx.ccx.sess.span_err(expr.span,
+ "bad index on obj");
+ }
+ auto meth = methods.(ix);
+ auto ty = plain_ty(ty_fn(meth.inputs, meth.output));
+ auto ann = ast.ann_type(ty);
+ ret @fold.respan[ast.expr_](expr.span,
+ ast.expr_field(base_1,
+ field,
+ ann));
+ }
+
case (_) {
fcx.ccx.sess.unimpl("base type for expr_field "
+ "in typeck.check_expr: "