gleam-lang / gleam

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

Certain code causes a function to not be generated even after passing type checking #3310

Open CrowdHailer opened 2 weeks ago

CrowdHailer commented 2 weeks 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 2 weeks 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 2 weeks 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
}