roc-lang / roc

A fast, friendly, functional language.
https://roc-lang.org
Universal Permissive License v1.0
4.19k stars 300 forks source link

Stack overflow with higher order functions #6485

Open Trivernis opened 8 months ago

Trivernis commented 8 months ago

When trying to compile this program that binds one parameter to a function, composes that function with itself and then uses List.map to call both the bound function and the composed function the build fails with a stack overflow error. This happens when building it in dev mode too. Also querying the language server for the signature of any of the elements involved crashes it.

app "crash-me"
    packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.7.1/Icc3xJoIixF3hCcfXrDwLCu4wQHtNdPyoJkEbkgIElA.tar.br" }
    imports [pf.Stdout]
    provides [main] to pf

main =
    fn1 = bind Num.sub 2
    fn2 = compose fn1 fn1

    results =
        [fn1, fn2]
        |> List.map \f -> f 2
        |> List.map Num.toStr
        |> Str.joinWith "\n"
    Stdout.line "$(results)"

bind : (a, b -> c), a -> (b -> c)
bind = \fn, a ->
    \b -> fn a b

compose : (a -> b), (b -> c) -> (a -> c)
compose = \fn1, fn2 ->
    \a -> fn1 a |> fn2

Version: roc nightly pre-release, built from commit dd86b11 on Di 30 Jan 2024 09:01:54 UTC Target: x86_64 Linux

LLDB if that's helpful

Process 72619 stopped and restarted: thread 1 received signal: SIGCHLD
Process 72619 stopped
* thread #2, name = 'roc', stop reason = signal SIGSEGV: address access protected (fault address: 0x7ffff7000ff0)
    frame #0: 0x00005555562e5e84 roc`___lldb_unnamed_symbol13042 + 20
roc`___lldb_unnamed_symbol13042:
->  0x5555562e5e84 <+20>: movq   %rdi, 0x70(%rsp)
    0x5555562e5e89 <+25>: movq   (%rsi), %rdi
    0x5555562e5e8c <+28>: movq   %rsi, 0x90(%rsp)
    0x5555562e5e94 <+36>: movq   0x28(%rsi), %r13
Anton-4 commented 8 months ago

Thanks for reporting this @Trivernis :)

Some extra data; this happens during the building of the app, not during the execution:

$ roc build main.roc

thread '<unknown>' has overflowed its stack
fatal runtime error: stack overflow
Aborted (core dumped)
barendventer commented 4 months ago

I think I might have run into this, here is a one-liner that gets a similar error message:

four = \_ -> (((((\f -> \x -> f (f x))(\f -> \x -> f (f x))))(\x -> x + 1))(0))

Defining this function in the REPL is enough to cause a stack overflow and crash it.

This example also doesn't involve any recursion, so it rules that out.

EDIT: For another example, the Y combinator doesn't give a type error like you'd expect, defining it (y = \f -> (\x -> f (x x)) (\x -> f (x x))) instead causes a stack overflow to happen