Skip to content

Commit 4fc8de1

Browse files
committed
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!).
1 parent b8bb2e1 commit 4fc8de1

File tree

3 files changed

+37
-6
lines changed

3 files changed

+37
-6
lines changed

src/comp/front/parser.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -899,7 +899,7 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr {
899899
some(token.COMMA),
900900
pf, p);
901901
hi = es.span;
902-
auto ex = ast.expr_call_self(e, es.node, ast.ann_none);
902+
ex = ast.expr_call_self(e, es.node, ast.ann_none);
903903
}
904904

905905
case (_) {

src/comp/middle/trans.rs

+30-5
Original file line numberDiff line numberDiff line change
@@ -3605,20 +3605,23 @@ type generic_info = rec(@ty.t item_type,
36053605
type lval_result = rec(result res,
36063606
bool is_mem,
36073607
option.t[generic_info] generic,
3608-
option.t[ValueRef] llobj);
3608+
option.t[ValueRef] llobj,
3609+
option.t[@ty.t] method_ty);
36093610

36103611
fn lval_mem(@block_ctxt cx, ValueRef val) -> lval_result {
36113612
ret rec(res=res(cx, val),
36123613
is_mem=true,
36133614
generic=none[generic_info],
3614-
llobj=none[ValueRef]);
3615+
llobj=none[ValueRef],
3616+
method_ty=none[@ty.t]);
36153617
}
36163618

36173619
fn lval_val(@block_ctxt cx, ValueRef val) -> lval_result {
36183620
ret rec(res=res(cx, val),
36193621
is_mem=false,
36203622
generic=none[generic_info],
3621-
llobj=none[ValueRef]);
3623+
llobj=none[ValueRef],
3624+
method_ty=none[@ty.t]);
36223625
}
36233626

36243627
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,
38133816
C_int(ix as int)));
38143817

38153818
auto lvo = lval_mem(r.bcx, v);
3816-
ret rec(llobj = some[ValueRef](r.val) with lvo);
3819+
let @ty.t fn_ty = ty.method_ty_to_fn_ty(methods.(ix));
3820+
ret rec(llobj = some[ValueRef](r.val),
3821+
method_ty = some[@ty.t](fn_ty)
3822+
with lvo);
38173823
}
38183824
case (_) { cx.fcx.ccx.sess.unimpl("field variant in trans_field"); }
38193825
}
@@ -4426,6 +4432,11 @@ fn trans_call(@block_ctxt cx, @ast.expr f,
44264432
option.t[ValueRef] lliterbody,
44274433
vec[@ast.expr] args,
44284434
&ast.ann ann) -> result {
4435+
4436+
// NB: 'f' isn't necessarily a function; it might be an entire self-call
4437+
// expression because of the hack that allows us to process self-calls
4438+
// with trans_call.
4439+
44294440
auto f_res = trans_lval(cx, f);
44304441
auto faddr = f_res.res.val;
44314442
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,
44494460
llenv = bcx.build.Load(llclosure);
44504461
}
44514462
}
4452-
auto fn_ty = ty.expr_ty(f);
4463+
4464+
let @ty.t fn_ty;
4465+
alt (f_res.method_ty) {
4466+
case (some[@ty.t](?meth)) {
4467+
// self-call
4468+
fn_ty = meth;
4469+
}
4470+
4471+
case (_) {
4472+
fn_ty = ty.expr_ty(f);
4473+
4474+
}
4475+
4476+
}
4477+
44534478
auto ret_ty = ty.ann_to_type(ann);
44544479
auto args_res = trans_args(f_res.res.bcx,
44554480
llenv, f_res.llobj,

src/comp/middle/ty.rs

+6
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ type method = rec(ast.proto proto,
2626

2727
type mt = rec(@t ty, ast.mutability mut);
2828

29+
// Convert from method type to function type. Pretty easy; we just drop
30+
// 'ident'.
31+
fn method_ty_to_fn_ty(method m) -> @ty.t {
32+
ret plain_ty(ty_fn(m.proto, m.inputs, m.output));
33+
}
34+
2935
// NB: If you change this, you'll probably want to change the corresponding
3036
// AST structure in front/ast.rs as well.
3137
type t = rec(sty struct, option.t[str] cname);

0 commit comments

Comments
 (0)