plow-technologies / inferno

A statically-typed functional scripting language
MIT License
4 stars 1 forks source link

Type inference crashes on large pattern (mis)match #54

Open siddharth-krishna opened 1 year ago

siddharth-krishna commented 1 year ago
let foo =
  fun input0 input1 input2 input3 input4 input5 input6 input7 input8 input9 input10 ->
    let latestValue = fun i -> Some 0.0 in
    match (latestValue input0, latestValue input1, latestValue input2, latestValue input3, latestValue input4, latestValue input5, latestValue input6, latestValue input7, latestValue input8, latestValue input9, latestValue input10, latestValue input0) with {
      | (Some x0, Some x1, Some x2, Some x3, Some x4, Some x5, Some x6, Some x7, Some x8, Some x9, Some x10) ->
        Some (truncateTo 2 (x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10))
      | _ -> None }
in foo 0 0 0 0 0 0 0 0 0 0 0

This script results in:

inferno: Prelude.undefined
CallStack (from HasCallStack):
  error, called at libraries/base/GHC/Err.hs:74:14 in base:GHC.Err
  undefined, called at src/Inferno/Infer/Error.hs:75:12 in inferno-core-0.3.1-inplace:Inferno.Infer.Error

This only happens when you try to match a 11-tuple with a 12-tuple. For smaller numbers you get the correct type error.

Here's a script to generate such examples:

script = '''
let foo =
fun {funArgs} ->
let latestValue = fun i -> Some 0.0 in
match ({matchArgs}) with {{
| ({pat}) ->
Some (truncateTo 2 ({sum}))
| _ -> None }}
in foo {callArgs}'''
def mk_script(n):
    args = [f'input{i}' for i in range(n)]
    with open('big-match.inferno', 'w') as f:
        f.write(script.format(
            funArgs=' '.join(args),
            matchArgs=', '.join((f'latestValue {i}' for i in args + args[0:1])),
            pat=', '.join((f'Some x{i}' for i in range(n))),
            sum=' + '.join(f'x{i}' for i in range(n)),
            callArgs=' '.join(('0' for i in range(n)))
        ))
mk_script(11)