gleam-lang / gleam

⭐️ A friendly language for building type-safe, scalable systems!
https://gleam.run
Apache License 2.0
17.97k stars 750 forks source link

wasm version of compiler not rejecting unsupported code for JS target #3310

Closed CrowdHailer closed 3 weeks ago

CrowdHailer commented 4 months ago

I have extracted this reproduction from my project but not yet managed to reduce the function much. The following can be copied in the tour code playground an it breaks as follows.

Type checking passes, but the underline function is no in scope at runtime.

import gleam/io
import gleam/bit_array
import gleam/list

fn underline(code, errors) {
  let code = bit_array.from_string(code)
  let #(_, _, acc) =
    list.fold(errors, #(code, 0, []), fn(state, error) {
      let #(remaining, offset, acc) = state
      let #(#(start, end), reason) = error
      let pre = start - offset
      let emp = end - start
      let offset = end
      case code {
        <<pre:bytes-size(pre), emp:bytes-size(emp), remaining:bytes>> -> {
          let assert Ok(pre) = bit_array.to_string(pre)
          let acc = case pre {
            "" -> acc
            content -> [content,..acc]
          }
          let assert Ok(emp) = bit_array.to_string(emp)
          let acc = case emp {
            "" -> acc
            content -> [content,..acc]
          }
          #(remaining, offset, acc)
        }
        _ -> panic
      }
    })
  list.reverse(acc)
}

pub fn main() {
    underline  
}

You can check that this is weird by replacing main with.

pub fn main() {
  fn() { underline }  
}
lpil commented 4 months ago

Could you give more detail on this please? This does not compile on JS, but I get a compile bug on Erlang, but neither is the issue you've described?

CrowdHailer commented 4 months ago

https://vimeo.com/965940552/86b69701a5?share=copy

Walk through of the issue hopefully gives more context Along with the smaller repro

import gleam/io
import gleam/bit_array
import gleam/list

fn underline(code) {
  let code = bit_array.from_string(code)
  let pre = 2
  case code {
        <<pre:bytes-size(pre),  remaining:bytes>> -> {
          #(pre, remaining)

        }
        _ -> panic
      }
}

pub fn main() {
   io.debug("hhello!")
    underline("hello")
    |> io.debug
}
lpil commented 4 months ago

Thank you 💜

Acepie commented 4 months ago

FYI looks like this might be something specific to running the example in the tour. If you try to run this code in node/on local then you properly get a compile error

Screenshot 2024-07-12 221607

lpil commented 4 months ago

Oh spooky! What's going on there