ponyc
ponyc copied to clipboard
Compiler segmentation fault on complex Map union types
This code causes a segmentation fault during compilation on latest release:
use "collections"
actor Main
let map: Map[String, (F32 | Map[U32, F32])] = map.create()
new create(env: Env) => None
Building builtin -> /usr/local/Cellar/ponyc/0.25.0/packages/builtin
Building . -> /Users/Eric/tmp
Building collections -> /usr/local/Cellar/ponyc/0.25.0/packages/collections
Building ponytest -> /usr/local/Cellar/ponyc/0.25.0/packages/ponytest
Building time -> /usr/local/Cellar/ponyc/0.25.0/packages/time
[1] 3335 segmentation fault ponyc
$ ponyc --version
0.25.0 [release]
compiled with: llvm 3.9.1 -- Apple LLVM version 10.0.0 (clang-1000.11.45.2)
Defaults: pic=false ssl=openssl_0.9.0
This seems to be a more general issue with type parameters. Here's a more minimal example:
actor Main
let a: Array[(Array[I8] | I8)]
new create(env: Env) =>
a = []
This seems to be resulting in infinite recursion of this sequence of calls:
exact_nominal( Array[I8 val] ref, Array[(Array[I8 val] ref | I8 val)] ref )
is_eq_typeargs( Array[I8 val] ref, Array[(Array[I8 val] ref | I8 val)] ref )
is_eqtype( I8 val, (Array[I8 val] ref | I8 val) )
is_x_sub_x( I8 val, (Array[I8 val] ref | I8 val) )
is_nominal_sub_x( I8 val, (Array[I8 val] ref | I8 val) )
is_x_sub_x( I8 val, Array[I8 val] ref )
is_nominal_sub_x( I8 val, Array[I8 val] ref )
is_nominal_sub_nominal( I8 val, Array[I8 val] ref )
push_assume( I8 val, Array[I8 val] ref )
check_assume( I8 val, Array[I8 val] ref )
exact_nominal( I8 val, Array[(Array[I8 val] ref | I8 val)] ref )
is_nominal_sub_entity( I8 val, Array[I8 val] ref )
is_x_sub_x( I8 val, I8 val )
is_nominal_sub_x( I8 val, I8 val )
is_nominal_sub_nominal( I8 val, I8 val )
push_assume( I8 val, I8 val )
check_assume( I8 val, I8 val )
exact_nominal( I8 val, Array[(Array[I8 val] ref | I8 val)] ref )
is_nominal_sub_entity( I8 val, I8 val )
is_eq_typeargs( I8 val, I8 val )
is_x_sub_x( (Array[I8 val] ref | I8 val), I8 val )
is_x_sub_x( Array[I8 val] ref, I8 val )
is_nominal_sub_x( Array[I8 val] ref, I8 val )
is_nominal_sub_nominal( Array[I8 val] ref, I8 val )
push_assume( Array[I8 val] ref, I8 val )
check_assume( Array[I8 val] ref, I8 val )
Here's a backtrace (Using ReadSeq instead of Array)
This one's using array, like the example: https://gist.github.com/Theodus/a29405cc7f619494140535c5eea1adf0
I've isolated the frames that repeat (middle chunk, repeats at frame 12), with arguments:
(169) 0: is_subtype( I8 val, (Array[I8 val] ref | I8 val) )
1: is_eq_typeargs( Array[I8 val] ref, Array[(Array[I8 val] ref | I8 val)] ref )
2: exact_nominal( Array[I8 val] ref, Array[(Array[I8 val] ref | I8 val)] ref )
3: check_assume( Array[I8 val] ref, I8 val )
4: push_assume( Array[I8 val] ref, I8 val )
5: is_nominal_sub_nominal( Array[I8 val] ref, I8 val )
6: is_nominal_sub_x( Array[I8 val] ref, I8 val )
7: is_x_sub_x( Array[I8 val] ref, I8 val )
8: is_union_sub_x( (Array[I8 val] ref | I8 val), I8 val )
9: is_x_sub_x( (Array[I8 val] ref | I8 val), I8 val )
10: is_subtype( (Array[I8 val] ref | I8 val), I8 val )
11: is_eqtype( I8 val, (Array[I8 val] ref | I8 val) )
12: is_eq_typeargs( Array[I8 val] ref, Array[(Array[I8 val] ref | I8 val)] ref )
The only assumption in subtype_assume is
Array[(Array[I8 val] ref | I8 val)] ref <: Array[(Array[I8 val] ref | I8 val)] ref
whenever check_assume is called. That list doesn't seem to grow.