about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorLindsey Kuper <lkuper@mozilla.com>2011-04-05 16:17:47 -0700
committerLindsey Kuper <lkuper@mozilla.com>2011-04-05 16:26:31 -0700
commit4fc8de196977a0e5bb4f733f7aaeb1162e880eaa (patch)
tree9888cdb1305dd85a237df2271c93b849b241eec9 /src/comp
parentb8bb2e118e9815316320f946ef3fc7e6909ed7c9 (diff)
downloadrust-4fc8de196977a0e5bb4f733f7aaeb1162e880eaa.tar.gz
rust-4fc8de196977a0e5bb4f733f7aaeb1162e880eaa.zip
Last pieces of self-call support.
The last few pieces of the hack that lets us use trans.trans_call() to
translate self-calls, plus a fix for the parser buy that was
preventing self-call expressions from getting past parsing.
test/run-pass/obj-self.rs works now (as in it actually prints "hi!"
twice!).
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/front/parser.rs2
-rw-r--r--src/comp/middle/trans.rs35
-rw-r--r--src/comp/middle/ty.rs6
3 files changed, 37 insertions, 6 deletions
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index 31e470be84b..27fdc7feb2d 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -899,7 +899,7 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr {
                                            some(token.COMMA),
                                            pf, p);
             hi = es.span;
-            auto ex = ast.expr_call_self(e, es.node, ast.ann_none);
+            ex = ast.expr_call_self(e, es.node, ast.ann_none);
         }
 
         case (_) {
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index b61aa244ad5..6fcd7b376ba 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -3605,20 +3605,23 @@ type generic_info = rec(@ty.t item_type,
 type lval_result = rec(result res,
                        bool is_mem,
                        option.t[generic_info] generic,
-                       option.t[ValueRef] llobj);
+                       option.t[ValueRef] llobj,
+                       option.t[@ty.t] method_ty);
 
 fn lval_mem(@block_ctxt cx, ValueRef val) -> lval_result {
     ret rec(res=res(cx, val),
             is_mem=true,
             generic=none[generic_info],
-            llobj=none[ValueRef]);
+            llobj=none[ValueRef],
+            method_ty=none[@ty.t]);
 }
 
 fn lval_val(@block_ctxt cx, ValueRef val) -> lval_result {
     ret rec(res=res(cx, val),
             is_mem=false,
             generic=none[generic_info],
-            llobj=none[ValueRef]);
+            llobj=none[ValueRef],
+            method_ty=none[@ty.t]);
 }
 
 fn trans_external_path(@block_ctxt cx, ast.def_id did,
@@ -3813,7 +3816,10 @@ fn trans_field(@block_ctxt cx, &ast.span sp, ValueRef v, @ty.t t0,
                                                 C_int(ix as int)));
 
             auto lvo = lval_mem(r.bcx, v);
-            ret rec(llobj = some[ValueRef](r.val) with lvo);
+            let @ty.t fn_ty = ty.method_ty_to_fn_ty(methods.(ix));
+            ret rec(llobj = some[ValueRef](r.val),
+                    method_ty = some[@ty.t](fn_ty)
+                    with lvo);
         }
         case (_) { cx.fcx.ccx.sess.unimpl("field variant in trans_field"); }
     }
@@ -4426,6 +4432,11 @@ fn trans_call(@block_ctxt cx, @ast.expr f,
               option.t[ValueRef] lliterbody,
               vec[@ast.expr] args,
               &ast.ann ann) -> result {
+
+    // NB: 'f' isn't necessarily a function; it might be an entire self-call
+    // expression because of the hack that allows us to process self-calls
+    // with trans_call.
+
     auto f_res = trans_lval(cx, f);
     auto faddr = f_res.res.val;
     auto llenv = C_null(T_opaque_closure_ptr(cx.fcx.ccx.tn));
@@ -4449,7 +4460,21 @@ fn trans_call(@block_ctxt cx, @ast.expr f,
             llenv = bcx.build.Load(llclosure);
         }
     }
-    auto fn_ty = ty.expr_ty(f);
+
+    let @ty.t fn_ty;
+    alt (f_res.method_ty) {
+        case (some[@ty.t](?meth)) {
+            // self-call
+            fn_ty = meth;
+        }
+        
+        case (_) {
+            fn_ty = ty.expr_ty(f);
+
+        }
+
+    }
+
     auto ret_ty = ty.ann_to_type(ann);
     auto args_res = trans_args(f_res.res.bcx,
                                llenv, f_res.llobj,
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index 24bd647f450..f83bece7f20 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -26,6 +26,12 @@ type method = rec(ast.proto proto,
 
 type mt = rec(@t ty, ast.mutability mut);
 
+// Convert from method type to function type.  Pretty easy; we just drop
+// 'ident'.
+fn method_ty_to_fn_ty(method m) -> @ty.t {
+    ret plain_ty(ty_fn(m.proto, m.inputs, m.output));
+}
+
 // NB: If you change this, you'll probably want to change the corresponding
 // AST structure in front/ast.rs as well.
 type t = rec(sty struct, option.t[str] cname);