ponyc
ponyc copied to clipboard
Wrong reference capability for element of array literal in a recover block
The following program
class Foo
var n: USize
var bar: (Bar | None)
new create() =>
n = 0
bar = None
fun ref set_n(n': USize) =>
n = n'
fun ref set_bar(bar': Bar) =>
bar = bar'
class Bar
let _children: ReadSeq[Foo box] val
new create(children: ReadSeq[Foo box] val) =>
_children = children
class Baz
let _child: Foo box
new create(child: Foo box) =>
_child = child
actor Main
new create(env: Env) =>
let foo: Foo val =
recover
let f: Foo ref = Foo
f.set_n(3)
let z = Baz(f)
let b = Bar([f])
f.set_bar(b)
f
end
env.out.print(foo.n.string())
Produces the output
0.24.0 [release]
compiled with: llvm 3.9.1 -- cc (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609
Defaults: pic=false ssl=openssl_0.9.0
Error:
main.pony:36:22: array element not a subtype of specified array type
let b = Bar([f])
^
Info:
main.pony:19:32: array type: Foo box
new create(children: ReadSeq[Foo box] val) =>
^
main.pony:33:16: element type: Foo tag
let f: Foo ref = Foo
^
main.pony:33:16: Foo tag is not a subtype of Foo box: tag is not a subcap of box
let f: Foo ref = Foo
^
Error:
main.pony:37:19: cannot infer type of b
f.set_bar(b)
^
I don't see why the variable f
is being treated as a Foo tag
in the array literal.
The explicit recover block here is a red herring - this fails in the same way even if that is removed.
The array inference logic here is flawed: https://github.com/ponylang/ponyc/blob/46668e275032586af18f2495d5b99a36cf106951/src/libponyc/expr/array.c#L379-L385
Here, the right side is coming back as Array[Foo ref]
, while the antecedent is Array[Foo box]
. Even though Foo ref
is a subtype of Foo box
, the same isn't true of Array[Foo ref]
and Array[Foo box]
. The logic needs to do something else here - it needs to recognize the subtype relationship for the element type, and then just use the antecedent type directly without trying to recover. That check should happen before this check I'm highlighting here, but it isn't.
I can't guarantee I'll find time for this soon, but I'll try. I'll assign myself to this ticket if I start working on it. Otherwise, it's fair game for someone else.