roc-lang / roc

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

Cannot chain `Ok` in expression containing try operator #7080

Open ageron opened 2 months ago

ageron commented 2 months ago

This code fails using roc nightly pre-release, built from commit 9a4d556 on Mon Sep 9 09:02:33 UTC 2024:

app [main] {
    pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.15.0/SlwdbJ-3GR7uBWQo6zlmYWNYOxnvo8r6YABXD-45UOw.tar.br",
}

import pf.Stdout

inc = \i ->
    if i > 2 then
        Err MaxReached
    else
        Ok (i + 1)

run = \i ->
    i
    |> inc?
    |> inc?
    |> Ok

main =
    result = run 0
    Stdout.line! "Result: $(result |> Inspect.toStr)"

The error is:

An internal compiler expectation was broken.
This is definitely a compiler bug.
Please file an issue here: <https://github.com/roc-lang/roc/issues/new/choose>
a Expr::TrySuffix expression was not completely removed in desugar_value_def_suffixed
Location: crates/compiler/can/src/expr.rs:1125:40

The problem disappears if I use an intermediate variable:

run = \i ->
    newi =
        i
        |> inc?
        |> inc?
    Ok newi

Alternatively, the problem also disappears if I stop using the try operator:

inc2 = \i ->
    i + 1

run = \i ->
    i
    |> inc2
    |> inc2
    |> Ok

So there seems to be something fishy with the combination of |> Ok and the ? operator.