Skip to content

Commit 130006c

Browse files
committed
Tie the knot for self-calls inside extended objects. Closes #539.
1 parent cf4c2ac commit 130006c

File tree

2 files changed

+9
-10
lines changed

2 files changed

+9
-10
lines changed

src/comp/middle/trans.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7829,7 +7829,7 @@ fn process_fwding_mthd(@local_ctxt cx, &span sp, @ty::method m,
78297829
ty::t[] additional_field_tys) -> ValueRef {
78307830

78317831
// NB: self_ty (and llself_ty) is the type of the outer object;
7832-
// with_obj_ty (and llwith_obj_ty) is the type of the inner object.
7832+
// with_obj_ty is the type of the inner object.
78337833

78347834
// The method m is being called on the outer object, but the outer object
78357835
// 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,
78707870
auto llself_obj_ptr = alloca(bcx, llself_ty);
78717871
bcx.build.Store(fcx.llenv, llself_obj_ptr);
78727872

7873+
// Grab hold of the outer object so we can pass it into the inner object,
7874+
// in case that inner object needs to make any self-calls. (Such calls
7875+
// will need to dispatch back through the outer object.)
7876+
auto llself_obj = bcx.build.Load(llself_obj_ptr);
7877+
78737878
// The 'llretptr' that will arrive in the forwarding function we're
78747879
// creating also needs to be the correct size. Cast it to the size of the
78757880
// method's return type, if necessary.
@@ -7961,11 +7966,10 @@ fn process_fwding_mthd(@local_ctxt cx, &span sp, @ty::method m,
79617966

79627967
// Set up the original method to be called.
79637968
auto orig_mthd_ty = ty::method_ty_to_fn_ty(cx.ccx.tcx, *m);
7964-
auto llwith_obj_ty = val_ty(llwith_obj.val);
79657969
auto llorig_mthd_ty =
79667970
type_of_fn_full(bcx.fcx.lcx.ccx, sp,
79677971
ty::ty_fn_proto(bcx.fcx.lcx.ccx.tcx, orig_mthd_ty),
7968-
some[TypeRef](llwith_obj_ty),
7972+
some[TypeRef](llself_ty),
79697973
m.inputs,
79707974
m.output,
79717975
vec::len[ast::ty_param](ty_params));
@@ -7976,7 +7980,7 @@ fn process_fwding_mthd(@local_ctxt cx, &span sp, @ty::method m,
79767980
// Set up the three implicit arguments to the original method we'll need
79777981
// to call.
79787982
let vec[ValueRef] llorig_mthd_args = [llretptr, fcx.lltaskptr,
7979-
llwith_obj.val];
7983+
llself_obj];
79807984

79817985
// Copy the explicit arguments that are being passed into the forwarding
79827986
// function (they're in fcx.llargs) to llorig_mthd_args.

src/test/run-pass/anon-obj-degenerate.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
//xfail-stage0
2-
//xfail-stage1
3-
//xfail-stage2
42
use std;
53

64
fn main() {
@@ -17,13 +15,10 @@ fn main() {
1715
auto my_a = a();
1816

1917
// Degenerate anonymous object: one that doesn't add any new
20-
// methods or fields. Adding support for this is issue #539.
21-
// (Making this work will also ensure that calls to anonymous
22-
// objects "fall through" appropriately.)
18+
// methods or fields.
2319

2420
auto my_d = obj() { with my_a };
2521

26-
// Right now, this fails with "unknown method 'foo' of obj".
2722
assert (my_d.foo() == 2);
2823
assert (my_d.bar() == 2);
2924

0 commit comments

Comments
 (0)