ponyc icon indicating copy to clipboard operation
ponyc copied to clipboard

`this` cap instantiated incorrectly for `trn` receivers calling `box` methods

Open jasoncarr0 opened this issue 5 years ago • 4 comments

When calling a box method on a trn expression, automatic receiver recovery seems to occur without proper checks, and the result is ref. I suspect this occurs because the return type cannot be correctly checked until after we've decided whether the method should be called as ref or box. No such issue appears to occur with iso.

class Bar
class Foo
  let bar: Bar = Bar
  fun get(): this->Bar =>
    this.bar

actor Main
  new create(env: Env) =>
    let foo = recover trn Foo end
    let bar_ref: Bar ref = foo.get() // Notice this returns `Bar ref`
    let bar_val: Bar val = (consume val foo).bar
    env.out.print((bar_ref is bar_val).string())

This is independent of the subtype changes. This ambiguity also occurs with ref or val but there is no issue without receiver recovery being allowed.

jasoncarr0 avatar Nov 03 '20 01:11 jasoncarr0

Most probable explanation: this was latent until the change to allow returning box for trn recovery. TK_THISTYPE likely gets instantiated as box and then the trn receiver sees the result as safe to recover, and becomes ref.

jasoncarr0 avatar Nov 03 '20 01:11 jasoncarr0

Proposed solution from Jason during the sync call: when doing receiver recovery on a box call, we should reify this as ref instead of box inside the call.

jemc avatar Nov 10 '20 19:11 jemc

@jemc where does the receiver recovery code live in the codebase?

SeanTAllen avatar Jan 29 '22 14:01 SeanTAllen

I think it's roughly around here: https://github.com/ponylang/ponyc/blob/065d70a9b7116195fbfda37f761fdd1ca4231cd7/src/libponyc/expr/call.c#L272-L273

jemc avatar Jan 29 '22 16:01 jemc