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!).
This commit is contained in:
parent
b8bb2e118e
commit
4fc8de1969
3 changed files with 37 additions and 6 deletions
|
@ -899,7 +899,7 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr {
|
||||||
some(token.COMMA),
|
some(token.COMMA),
|
||||||
pf, p);
|
pf, p);
|
||||||
hi = es.span;
|
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 (_) {
|
case (_) {
|
||||||
|
|
|
@ -3605,20 +3605,23 @@ type generic_info = rec(@ty.t item_type,
|
||||||
type lval_result = rec(result res,
|
type lval_result = rec(result res,
|
||||||
bool is_mem,
|
bool is_mem,
|
||||||
option.t[generic_info] generic,
|
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 {
|
fn lval_mem(@block_ctxt cx, ValueRef val) -> lval_result {
|
||||||
ret rec(res=res(cx, val),
|
ret rec(res=res(cx, val),
|
||||||
is_mem=true,
|
is_mem=true,
|
||||||
generic=none[generic_info],
|
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 {
|
fn lval_val(@block_ctxt cx, ValueRef val) -> lval_result {
|
||||||
ret rec(res=res(cx, val),
|
ret rec(res=res(cx, val),
|
||||||
is_mem=false,
|
is_mem=false,
|
||||||
generic=none[generic_info],
|
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,
|
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)));
|
C_int(ix as int)));
|
||||||
|
|
||||||
auto lvo = lval_mem(r.bcx, v);
|
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"); }
|
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,
|
option.t[ValueRef] lliterbody,
|
||||||
vec[@ast.expr] args,
|
vec[@ast.expr] args,
|
||||||
&ast.ann ann) -> result {
|
&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 f_res = trans_lval(cx, f);
|
||||||
auto faddr = f_res.res.val;
|
auto faddr = f_res.res.val;
|
||||||
auto llenv = C_null(T_opaque_closure_ptr(cx.fcx.ccx.tn));
|
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);
|
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 ret_ty = ty.ann_to_type(ann);
|
||||||
auto args_res = trans_args(f_res.res.bcx,
|
auto args_res = trans_args(f_res.res.bcx,
|
||||||
llenv, f_res.llobj,
|
llenv, f_res.llobj,
|
||||||
|
|
|
@ -26,6 +26,12 @@ type method = rec(ast.proto proto,
|
||||||
|
|
||||||
type mt = rec(@t ty, ast.mutability mut);
|
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
|
// NB: If you change this, you'll probably want to change the corresponding
|
||||||
// AST structure in front/ast.rs as well.
|
// AST structure in front/ast.rs as well.
|
||||||
type t = rec(sty struct, option.t[str] cname);
|
type t = rec(sty struct, option.t[str] cname);
|
||||||
|
|
Loading…
Reference in a new issue