roc-lang / roc

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

Upgrade basic-cli to purity inference roc panics `Option::unwrap()` on a `None` value #7208

Open lukewilliamboswell opened 1 week ago

lukewilliamboswell commented 1 week ago

In this commit

$ roc examples/tcp-client.roc
thread '<unnamed>' panicked at crates/compiler/mono/src/ir.rs:6191:56:
called `Option::unwrap()` on a `None` value
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
app [main!] { pf: platform "../platform/main.roc" }

import pf.Tcp
import pf.Stdout
import pf.Stdin
import pf.Stderr

main! = \{} ->
    when run! {} is
        Ok {} -> Ok {}
        Err err -> handleErr! err

handleErr! : []_ => Result {} _
handleErr! = \error ->
    when error is
        TcpConnectErr err ->
            errStr = Tcp.connectErrToStr err
            Stderr.line!
                """
                Failed to connect: $(errStr)

                If you don't have anything listening on port 8085, run:
                \$ nc -l 8085

                If you want an echo server you can run:
                $ ncat -e \$(which cat) -l 8085
                """

        TcpReadBadUtf8 _ ->
            Stderr.line! "Received invalid UTF-8 data"

        TcpReadErr err ->
            errStr = Tcp.streamErrToStr err
            Stderr.line! "Error while reading: $(errStr)"

        TcpWriteErr err ->
            errStr = Tcp.streamErrToStr err
            Stderr.line! "Error while writing: $(errStr)"

        other -> Stderr.line! "Got other error: $(Inspect.toStr other)"

run! : {} => Result {} _
run! = \{} ->

    stream = try Tcp.connect! "127.0.0.1" 8085

    try Stdout.line! "Connected!"

    loop! {} \_ ->
        Result.map (tick! stream) Step

tick! : Tcp.Stream => Result {} _
tick! = \stream ->
    try Stdout.write! "> "

    outMsg = try Stdin.line! {}

    try Tcp.writeUtf8! stream "$(outMsg)\n"

    inMsg = try Tcp.readLine! stream

    Stdout.line! "< $(inMsg)"

loop! : state, (state => Result [Step state, Done done] err) => Result done err
loop! = \state, fn! ->
    when fn! state is
        Err err -> Err err
        Ok (Done done) -> Ok done
        Ok (Step next) -> loop! next fn!