ponyc
ponyc copied to clipboard
Tuple literals not matching correctly
Summary
While trying to build a simple "event sourcing" style application I ran into problems with tuple matching.
Essentially if I build a tuple as a literal:
let cc: Change = ((0,0), "bob", Dependency, (Link, "123"))
then the subsequent match matches incorrectly (not just a failed match but an incorrect match).
While, if I build the same tuple in two steps:
let vv: DependencyOp = (Link, "123")
let cc: Change = ((0,0), "bob", Dependency, vv)
The ponyc version is: 0.19.0-cf45938 [release]
Example Code
Bellow is a pared down version of my code that includes just the enough of the types in order to be able to trigger the problem. Note if Change has only the DependencyOp command in its type definition (versus including the NOP command) then the problem goes away and the tests succeed.
cat _test_tuples.pony
use "pony_test"
use "collections"
// -- types
type TimeStamp is (I64, I64)
type Principal is String
primitive NOP
primitive Dependency
primitive Link
primitive Unlink
primitive Spawn
type ID is String
type DependencyOp is ((Link, ID) | (Unlink, ID) | Spawn)
type Change is (
// when principal aspect value
( TimeStamp , Principal , NOP , None ) // <-- needed in order to trigger the bug
| ( TimeStamp , Principal , Dependency , DependencyOp )
// ... other journal command types
)
// -- tests
actor Main is TestList
new create(env: Env) =>
PonyTest(env, this)
new make() =>
None
fun tag tests(test: PonyTest) =>
test(_TestTupleNestLiteral)
test(_TestTupleNestConstructed)
// --
class iso _TestTupleNestLiteral is UnitTest
fun name(): String => "tuplenest:literal"
fun ref apply(h: TestHelper) =>
// building the Change using the following literal tuple does _not_ matche correctly
let cc: Change = ((0,0), "bob", Dependency, (Link, "123"))
CheckChange.check(cc,h)
class iso _TestTupleNestConstructed is UnitTest
fun name(): String => "tuplenest:constructed"
fun ref apply(h: TestHelper) =>
// building the Change using the following construction matches correctly
let vv: DependencyOp = (Link, "123")
let cc: Change = ((0,0), "bob", Dependency, vv)
CheckChange.check(cc,h)
primitive CheckChange
fun check(cc: Change, h: TestHelper) =>
match(cc)
| ( let t: TimeStamp , let p: Principal, let a: Dependency, let v: DependencyOp ) =>
match (v)
| (Link, let vw: ID) => h.complete(true)
| (Unlink, let vw: ID) => h.fail("expected link - got unlink")
| (Spawn) => h.fail("expected link - got spawn")
end
else
h.fail("didn't match outer")
end
Example Output
130 09:57 stewart@flatfoot:~/opt/pony/bugs/tuple-literal$ export PONYC=~/opt/pony/bleed/build/release/ponyc; ${PONYC} -d; ./tuple-literal ; ${PONYC} -v
Building builtin -> /home/stewart/opt/pony/bleed/packages/builtin
Building . -> /home/stewart/opt/pony/bugs/tuple-literal
Building ponytest -> /home/stewart/opt/pony/bleed/packages/ponytest
Building time -> /home/stewart/opt/pony/bleed/packages/time
Building collections -> /home/stewart/opt/pony/bleed/packages/collections
Generating
Reachability
Selector painting
Data prototypes
Data types
Function prototypes
Functions
Descriptors
Writing ./tuple-literal.o
Linking ./tuple-literal
Warning: environment variable $CC undefined, using cc as the linker
1 test started, 0 complete: tuplenest:literal started
2 tests started, 0 complete: tuplenest:constructed started
2 tests started, 1 complete: tuplenest:literal complete
2 tests started, 2 complete: tuplenest:constructed complete
**** FAILED: tuplenest:literal
expected link - got spawn
---- Passed: tuplenest:constructed
----
---- 2 tests ran.
---- Passed: 1
**** FAILED: 1 test, listed below:
**** FAILED: tuplenest:literal
0.19.0-cf45938 [release]
compiled with: llvm 3.9.1 -- cc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
At first glance, I think this might be a "tuple of unions vs union of tuples" issue, which is a known limitation of the compiler (see https://github.com/ponylang/ponyc/issues/1892). But I could be wrong, as I haven't looked at it in detail.
It's also possible this is related to the change in #1937. This could be confirmed by testing against ponyc version 0.14.0 or earlier.
I tested this with the Wallaroo Labs ponyc version (which is ponyc 0.9 more or less) and it worked then. can confirm it doesnt work with 0.19.0. Also works with 0.14.0. Does not work with 0.15.0.
Okay, sounds like it's a side effect of #1937, then.
Removing "needs discussion", this still needs to be investigated.
@jemc do you know if you ever looked into this? i'm assuming no.
No, I haven't looked into it.