ipso
ipso copied to clipboard
Nested patterns are incorrectly desugared
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.