Skip to content

Gleam Javascript miscompiles some string pattern matches. #6168

Description

@schurhammer

gleam 1.18.1

The pattern match below should take the 400 branch, but in gleam javascript it takes the 999 branch.

Also note this bug is not caused exclusively by guards (see second repro), it's about string matches "shadowing" prefix matches when they shouldn't.

pub fn w1(s: String, x: Int) -> Int {
  case s, x {
    "ab", y if y > 4 -> 1
    "a" <> _, _ -> 400
    _, _ -> 999
  }
}

pub fn main() {
  echo w1("ab", 1)
}

Compiles to:

export function w1(s, x) {
  if (s === "ab") {
    let y = x;
    if (y > 4) {
      return 1;
    } else {
      return 999;
    }
  } else if (s.charCodeAt(0) === 97) {
    return 400;
  } else {
    return 999;
  }
}

Second one: should be 502 but prints 999

import gleam/string

pub type Shape {
  Circle(r: Int)
  Square(s: Int)
  Rect(w: Int, h: Int)
}

pub type Wrap {
  Wrapped(v: Shape)
  Empty
}

pub fn a(w: Wrap, s: String) -> Int {
  case w, s {
    _, "ab" -> 100
    Wrapped(Square(0)), "ab" <> _ -> 200
    Wrapped(_), "a" <> r -> 500 + string.length(r)
    _, _ -> 999
  }
}

pub fn main() {
  echo a(Wrapped(Rect(2, 1)), "abc")
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions