diff options
| author | Lindsey Kuper <lkuper@mozilla.com> | 2011-07-06 18:25:51 -0700 |
|---|---|---|
| committer | Lindsey Kuper <lkuper@mozilla.com> | 2011-07-06 18:39:01 -0700 |
| commit | 130006cdda2f40872f6b44665a9b2a0d2d9ded52 (patch) | |
| tree | 6592ad6893b0e1848234c29378a21dfaf850e153 | |
| parent | cf4c2ac0bee9a23a5f3ec230c6ea54fb2281dbcb (diff) | |
Tie the knot for self-calls inside extended objects. Closes #539.
| -rw-r--r-- | src/comp/middle/trans.rs | 12 | ||||
| -rw-r--r-- | src/test/run-pass/anon-obj-degenerate.rs | 7 |
2 files changed, 9 insertions, 10 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 19a112afceb..e8139432ad2 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -7829,7 +7829,7 @@ fn process_fwding_mthd(@local_ctxt cx, &span sp, @ty::method m, ty::t[] additional_field_tys) -> ValueRef { // NB: self_ty (and llself_ty) is the type of the outer object; - // with_obj_ty (and llwith_obj_ty) is the type of the inner object. + // with_obj_ty is the type of the inner object. // The method m is being called on the outer object, but the outer object // doesn't have that method; only the inner object does. So what we have @@ -7870,6 +7870,11 @@ fn process_fwding_mthd(@local_ctxt cx, &span sp, @ty::method m, auto llself_obj_ptr = alloca(bcx, llself_ty); bcx.build.Store(fcx.llenv, llself_obj_ptr); + // Grab hold of the outer object so we can pass it into the inner object, + // in case that inner object needs to make any self-calls. (Such calls + // will need to dispatch back through the outer object.) + auto llself_obj = bcx.build.Load(llself_obj_ptr); + // The 'llretptr' that will arrive in the forwarding function we're // creating also needs to be the correct size. Cast it to the size of the // method's return type, if necessary. @@ -7961,11 +7966,10 @@ fn process_fwding_mthd(@local_ctxt cx, &span sp, @ty::method m, // Set up the original method to be called. auto orig_mthd_ty = ty::method_ty_to_fn_ty(cx.ccx.tcx, *m); - auto llwith_obj_ty = val_ty(llwith_obj.val); auto llorig_mthd_ty = type_of_fn_full(bcx.fcx.lcx.ccx, sp, ty::ty_fn_proto(bcx.fcx.lcx.ccx.tcx, orig_mthd_ty), - some[TypeRef](llwith_obj_ty), + some[TypeRef](llself_ty), m.inputs, m.output, vec::len[ast::ty_param](ty_params)); @@ -7976,7 +7980,7 @@ fn process_fwding_mthd(@local_ctxt cx, &span sp, @ty::method m, // Set up the three implicit arguments to the original method we'll need // to call. let vec[ValueRef] llorig_mthd_args = [llretptr, fcx.lltaskptr, - llwith_obj.val]; + llself_obj]; // Copy the explicit arguments that are being passed into the forwarding // function (they're in fcx.llargs) to llorig_mthd_args. diff --git a/src/test/run-pass/anon-obj-degenerate.rs b/src/test/run-pass/anon-obj-degenerate.rs index 721253376a7..dd0caf4bb4f 100644 --- a/src/test/run-pass/anon-obj-degenerate.rs +++ b/src/test/run-pass/anon-obj-degenerate.rs @@ -1,6 +1,4 @@ //xfail-stage0 -//xfail-stage1 -//xfail-stage2 use std; fn main() { @@ -17,13 +15,10 @@ fn main() { auto my_a = a(); // Degenerate anonymous object: one that doesn't add any new - // methods or fields. Adding support for this is issue #539. - // (Making this work will also ensure that calls to anonymous - // objects "fall through" appropriately.) + // methods or fields. auto my_d = obj() { with my_a }; - // Right now, this fails with "unknown method 'foo' of obj". assert (my_d.foo() == 2); assert (my_d.bar() == 2); |
