Open LPTK opened 2 years ago
[x] hygiene
:NewParser
:NewDefs
:NoJS
class Union<Region>(a: Region, b: Region)
//│ class Union[Region](a: Region, b: Region)
// * [FIXME:UCS] unhygienically desugars to:
// | | | | Desugared term: case x of { Union => let x = (x).a in let y = (x).b in x }
fun hmm(x) =
if x is Union(x, y) then x
//│ fun hmm: Union[{b: anything} & 'a] -> 'a
fun hmm(x) =
if x is Union(z, y) then x
//│ fun hmm: Union['Region] -> Union['Region]
:NewParser
:NewDefs
module Nil
class Cons[A](head: A, tail: Cons[A] | Nil)
//│ module Nil()
//│ class Cons[A](head: A, tail: Cons[A] | Nil)
// FIXME
fun filtermap(f, xs) = if xs is
Nil then Nil
Cons(y, ys) and f(ys) is
false then filtermap(f, ys)
true then Cons(y, filtermap(f, ys))
[true, z] then Cons(y, filtermap(f, ys))
//│ ╔══[ERROR] identifier not found: ys
//│ ║ l.26: Cons(y, ys) and f(ys) is
//│ ╙── ^^
//│ ╔══[ERROR] Type mismatch in application:
//│ ║ l.26: Cons(y, ys) and f(ys) is
//│ ║ ^^^^^^^^
//│ ║ l.27: false then filtermap(f, ys)
//│ ║ ^^^^^^^^^
//│ ╟── reference of type `false` is not an instance of type `number`
//│ ║ l.27: false then filtermap(f, ys)
//│ ╙── ^^^^^
//│ ╔══[ERROR] Type mismatch in application:
//│ ║ l.26: Cons(y, ys) and f(ys) is
//│ ║ ^^^^^^^^
//│ ║ l.27: false then filtermap(f, ys)
//│ ║ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//│ ║ l.28: true then Cons(y, filtermap(f, ys))
//│ ║ ^^^^^^^^
//│ ╟── reference of type `true` is not an instance of type `number`
//│ ║ l.28: true then Cons(y, filtermap(f, ys))
//│ ╙── ^^^^
//│ ╔══[ERROR] type identifier not found: Tuple#2
//│ ╙──
//│ fun filtermap: ((error | Cons['A] | Nil) -> number & (Cons['A] | Nil) -> error, Cons['A0] | Nil,) -> (Cons['A1] | Nil | error)
//│ where
//│ 'A := 'A0
//│ 'A0 <: nothing
//│ Code generation encountered an error:
//│ unknown match case: Tuple#2
module True
module False
//│ module True()
//│ module False()
class Pair[A, B](lhs: A, rhs: B)
//│ class Pair[A, B](lhs: A, rhs: B)
fun filtermap(f, xs) = if xs is
Nil then Nil
Cons(y, ys) then if f(y) is
True then filtermap(f, ys)
False then Cons(y, filtermap(f, ys))
Pair(True, z) then Cons(z, filtermap(f, ys))
//│ fun filtermap: ('head -> (False | Pair[anything, 'A] | True), Cons['head] | Nil,) -> (Cons['A] | Nil)
//│ where
//│ 'head <: 'A
or
in shared/src/test/diff/ucs/Or.mlsand
in shared/src/test/diff/ucs/LeadingAnd.mls[x] Give warnings for non-conditional UCS. See https://github.com/hkust-taco/mlscript/blob/ee1ab193234e9d59ad0ce3fa82e2c922efd8d56e/shared/src/test/diff/nu/BadUCS.mls#L75
Update as of the introduction of new desugarer in Jan 2024: This case is interesting, it means that we bind x
to y
which shadows parameter y
, but someone may think it means if x == y then 0.
[ ] One more hygienic bindings thing to make sure and address
[ ] Warn against shadowing pattern variables
fun fold(opt, k, d) = if opt is
None then d
refined(Some) then k(opt)
else k(opt)
//│ ╔══[WARNING] inconsistent refined pattern
//│ ║ l.67: None then d
//│ ║ ^^^^
//│ ╟── pattern `Some` is refined
//│ ║ l.68: refined(Some) then k(opt)
//│ ║ ^^^^
//│ ╟── but pattern `None` is not refined
//│ ║ l.67: None then d
//│ ╙── ^^^^
Issue to track the parts of the UCS implementation that are still incomplete or wrong – please update with more cases as you find them.
Translation
Locations
Track scrutinee locations with. (Note: it was removed in new desugarer.)Scrutinee.Source
[x] No location reported in:
Reporting
is
test has a single pattern Though maybe we shouldn't warn when it's conjuncted with other things, as then theis
may be used to bind expressions, as inif xs is x :: xs and mapPartition(f, xs) is (as, bs) and ...