gleam-lang/gleam

Invalid Erlang code generated when comparing type containing a function in case guard

Open

#3,069 opened on Apr 29, 2024

View on GitHub
 (1 comment) (0 reactions) (0 assignees)Rust (960 forks)batch import
help wanted

Repository metrics

Stars
 (21,417 stars)
PR merge metrics
 (Avg merge 10d 19h) (69 merged PRs in 30d)

Description

The following Gleam code compiles to invalid Erlang code. The problem is due to the guard expression and the presence of a function in the type being compared.

The comparison works as expected if the equality check is done directly, i.e. foo == hello_greeting_wrapper.

Note that everything works correctly when targeting JavaScript, this is an Erlang-specific issue.

type GreetingWrapper {
  GreetingWrapper(greeting_fn: fn() -> String)
}

fn hello_greeting() {
  "Hello!"
}

const hello_greeting_wrapper = GreetingWrapper(hello_greeting)

fn is_hello(foo: GreetingWrapper) {
  case foo {
    f if f == hello_greeting_wrapper -> True
    _ -> False
  }
}

pub fn main() {
  is_hello(hello_greeting_wrapper)
}

The output from gleam run is:

Compiling bug_repro
/bug_repro/build/dev/erlang/bug_repro/_gleam_artefacts/bug_repro.erl:16:41: illegal guard expression
%   16|         F when F =:= {greeting_wrapper, fun hello_greeting/0} ->
%     |                                         ^

error: Shell command failure

There was a problem when running the shell command `escript`.

Tested on Gleam v1.1.0 on macOS.

Contributor guide