ipso icon indicating copy to clipboard operation
ipso copied to clipboard

Nested patterns are incorrectly desugared

Open LightAndLight opened this issue 10 months ago • 0 comments

Problem 1

The type checker expects a closed variant when an open one will do.

test.ipso:

test : (| Ok : (| Ok : String, r1 |), r2 |) -> String
test x = 
  case x of
    Ok (Ok a) -> "here: $a"
    _ -> "there"

main : IO ()
main = println <| test (Ok (Ok "hi"))
$ ipso test.ipso
test.ipso:4:5: error: expected type "()", got type "r1"
  |
4 |     Ok (Ok a) -> "here: $a"
  |     ^

Problem 2

Nested patterns aren't matched "simulataneously".

test.ipso:

test : (| Ok : (| Ok : String, Err : () |), Err : a |) -> String
test x = 
  case x of
    Ok (Ok a) -> "here: $a"
    _ -> "there"

main : IO ()
main = println <| test (Ok (Err ()))

Expected output:

$ ipso test.ipso
there

Actual output:

$ ipso test.ipso
thread 'main' panicked at 'incomplete pattern match', src/lib.rs:3128:29
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

The code

test : (| Ok : (| Ok : String, Err : () |), Err : a |) -> String
test x = 
  case x of
    Ok (Ok a) -> "here: $a"
    _ -> "there"

desugars to

test : (| Ok : (| Ok : String, Err : () |), Err : a |) -> String
test x = 
  case x of
    Ok x ->
      case x of
        Ok a -> "here: $a"
    _ -> "there"

before evaluation. The outer Ok is matched, but the inner Ok branch is not matched, which causes an incomplete pattern exception.

LightAndLight avatar Mar 10 '25 05:03 LightAndLight