ponyc
ponyc copied to clipboard
`this` cap instantiated incorrectly for `trn` receivers calling `box` methods
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.
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.
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 where does the receiver recovery code live in the codebase?
I think it's roughly around here: https://github.com/ponylang/ponyc/blob/065d70a9b7116195fbfda37f761fdd1ca4231cd7/src/libponyc/expr/call.c#L272-L273