Skip to content

Commit 0298463

Browse files
committed
disjoint upperbound
1 parent cc87059 commit 0298463

File tree

9 files changed

+136
-67
lines changed

9 files changed

+136
-67
lines changed

hkmc2/shared/src/main/scala/hkmc2/bbml/ConstraintSolver.scala

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -92,19 +92,23 @@ class ConstraintSolver(infVarState: InfVarUid.State, elState: Elaborator.State,
9292
cctx.nest(v -> nc) givenIn:
9393
v.state.upperBounds ::= nc
9494
v.state.lowerBounds.foreach(lb => constrainImpl(lb, nc))
95+
v.state.disjsub.foreach: d =>
96+
Type.disjoint(d.disjoint(v), bd.toBasic.simp.toBasic)(Set.empty)(using c = mutable.Map.empty)
97+
.foreach(_.foreach(k => DisjSub(d.disjoint ++ k, d.dss, d.cs).commit()))
9598
else
9699
log(s"New bound: ${v.showDbg} :> ${bd.showDbg}")
97100
cctx.nest(bd -> v) givenIn:
98101
v.state.lowerBounds ::= bd
99102
v.state.upperBounds.foreach(ub => constrainImpl(bd, ub))
100-
v.state.disjsub.foreach:(d)=>
101-
Type.disjoint(d.disjoint(v),bd.toBasic.simp)match
102-
case N=>
103+
v.state.disjsub.foreach: d =>
104+
Type.disjoint(d.disjoint(v), bd.toBasic.simp.toBasic)(Set.empty)(using c = mutable.Map.empty) match
105+
case N =>
103106
d.remove(v)
104107
if d.disjoint.isEmpty then
105108
d.dss.foreach(_.commit())
106-
d.cs.foreach((a,b)=>constrainImpl(a,b))
107-
case S(k)=>d.disjoint++=k
109+
d.cs.foreach((a, b) => constrainImpl(a, b))
110+
case S(k) =>
111+
k.foreach(k => DisjSub(d.disjoint ++ k, d.dss, d.cs).commit())
108112
case Conj(i, u, Nil) => (conj.i, conj.u) match
109113
case (_, Union(N, Nil)) =>
110114
// raise(ErrorReport(msg"Cannot solve ${conj.i.toString()} ∧ ¬⊥" -> N :: Nil))
@@ -120,32 +124,38 @@ class ConstraintSolver(infVarState: InfVarUid.State, elState: Elaborator.State,
120124
// raise(ErrorReport(msg"Cannot constrain ${conj.i.toString()} <: ${conj.u.toString()}" -> N :: Nil))
121125
cctx.err
122126
else
123-
val k=args2.flatMap(x=>Type.disjoint(x,x))
127+
val k = args2.flatMap: x =>
128+
val u = x.toBasic.simp.toBasic
129+
Type.disjoint(u, u)(Set.empty)(using c = mutable.Map.empty)
124130
if k.isEmpty then
125131
args1.zip(args2).foreach {
126132
case (a1, a2) => constrainImpl(a2, a1)
127133
}
128134
constrainImpl(ret1, ret2)
129135
constrainImpl(eff1, eff2)
130-
else if !k.contains(Nil)then
131-
DisjSub(mutable.Map.from(k.flatten),Nil,(ret1,ret2)::(eff1,eff2)::args2.zip(args1)).commit()
136+
else
137+
val cs = (ret1, ret2) :: (eff1, eff2) :: args2.zip(args1)
138+
k.reduce((x, y) => y.flatMap(y => x.map(_ ++ y))).foreach: k =>
139+
DisjSub(mutable.Map.from(k), Nil, cs).commit()
132140
case (Inter(S(fs:Ls[FunType])), Union(S(FunType(args2, ret2, eff2)), Nil)) =>
133-
val f=fs.filter(_.args.length===args2.length)
134-
val args=f.map(_.args).transpose
135-
val k=args2.flatMap(x=>Type.disjoint(x,x))
136-
if!k.contains(Nil)then
141+
val f = fs.filter(_.args.length === args2.length)
142+
val args = f.map(_.args).transpose
143+
val k = args2.flatMap: x =>
144+
val u = x.toBasic.simp.toBasic
145+
Type.disjoint(u, u)(Set.empty)(using c = mutable.Map.empty)
146+
if !k.contains(Nil) then
137147
// assume distinguished by the first arg
138148
constrainImpl(args2.head,args.head.foldLeft(Bot:Type)(_|_))
139-
args.head.iterator.zip(f).foreach:(a,b)=>
140-
val s=args2.zip(b.args).tail
141-
Type.disjoint(args2.head.toBasic.simp,a.toBasic.simp)match
149+
args.head.iterator.zip(f).foreach: (a, b) =>
150+
val s = args2.zip(b.args).tail
151+
Type.disjoint(args2.head.toBasic.simp.toBasic,a.toBasic.simp.toBasic)(Set.empty)(using c = mutable.Map.empty) match
142152
case N =>
143-
s.foreach((x,y)=>constrainImpl(x,y))
144-
constrainImpl(b.ret,ret2)
145-
constrainImpl(b.eff,eff2)
153+
s.foreach((x, y) => constrainImpl(x, y))
154+
constrainImpl(b.ret, ret2)
155+
constrainImpl(b.eff, eff2)
146156
case S(k) =>
147-
val ds=DisjSub(mutable.Map.from(k),Nil,(b.ret,ret2)::(b.eff,eff2)::s)
148-
ds.commit()
157+
val cs = (b.ret,ret2) :: (b.eff,eff2) :: s
158+
k.foreach(k => DisjSub(mutable.Map.from(k), Nil, cs).commit())
149159
case _ =>
150160
// raise(ErrorReport(msg"Cannot solve ${conj.i.toString()} <: ${conj.u.toString()}" -> N :: Nil))
151161
cctx.err

hkmc2/shared/src/main/scala/hkmc2/bbml/PrettyPrinter.scala

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,21 @@ class PrettyPrinter(output: String => Unit)(using Scope):
1111
output("Where:")
1212
bounds.foreach {
1313
case (lhs, rhs) => output(s" ${lhs.show} <: ${rhs.show}")
14+
case ((x, y), z, w) =>
15+
val g = s"${x.show}#${y.show}"
16+
val h = z.iterator.map { case (x, y) => s"${x.show}#${y.show}"}.mkString
17+
val b = w.iterator.map { case (x, y) => s"${x.show}<:${y.show}"}.mkString("")
18+
output(s" $g$h$b}")
1419
}
1520

1621
object PrettyPrinter:
1722
def apply(output: String => Unit)(using Scope): PrettyPrinter = new PrettyPrinter(output)
1823

1924
type Bound = (Type, Type) // * Type <: Type
25+
type DisjBound=(Bound,List[Bound],List[Bound])
2026

21-
private def collectBounds(ty: GeneralType): List[Bound] =
22-
val res = ListBuffer[Bound]()
27+
private def collectBounds(ty: GeneralType): List[Bound|DisjBound] =
28+
val res = ListBuffer[Bound|DisjBound]()
2329
val cache = MutSet[Uid[InfVar]]()
2430
object CollectBounds extends TypeTraverser:
2531
override def apply(pol: Boolean)(ty: GeneralType): Unit = ty match
@@ -31,6 +37,10 @@ object PrettyPrinter:
3137
res ++= state.upperBounds.map: bd =>
3238
apply(false)(bd)
3339
(v, bd)
40+
res ++= state.disjsub.map: d =>
41+
val ds = d.disjoint.iterator
42+
val k = ds.next()
43+
(k, ds.toList, d.cs.toList)
3444
super.apply(pol)(ty)
3545
case _ => super.apply(pol)(ty)
3646
CollectBounds(true)(ty)

hkmc2/shared/src/main/scala/hkmc2/bbml/TypeSimplifier.scala

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -191,15 +191,17 @@ class TypeSimplifier(tl: TraceLogger):
191191
tv.state.upperBounds = newUBs
192192
val isPos = Analysis.posVars.contains(tv)
193193
val isNeg = Analysis.negVars.contains(tv)
194-
// if (isPos && !isNeg && (Analysis.occsNum(tv) === 1 && {newLBs match { case (tv: IV) :: Nil => true; case _ => false }} || newLBs.forall(_.isSmall))) {
195-
if isPos && !isNeg && ({newLBs match { case (tv: IV) :: Nil => true; case _ => false }} || newLBs.forall(_ => true)) then {
196-
// if (isPos && !isNeg && ({newLBs match { case (tv: IV) :: Nil => true; case _ => false }})) {
197-
newLBs.foldLeft(Bot: Type)(_ | _)
198-
} else
199-
// if (isNeg && !isPos && (Analysis.occsNum(tv) === 1 && {newUBs match { case (tv: IV) :: Nil => true; case _ => false }} || newUBs.forall(_.isSmall))) {
200-
if isNeg && !isPos && ({newUBs match { case (tv: IV) :: Nil => true; case _ => false }} || newUBs.forall(_ => true)) then
201-
// if (isNeg && !isPos && ({newUBs match { case (tv: IV) :: Nil => true; case _ => false }})) {
202-
newUBs.foldLeft(Top: Type)(_ & _)
194+
if tv.state.disjsub.isEmpty then
195+
// if (isPos && !isNeg && (Analysis.occsNum(tv) === 1 && {newLBs match { case (tv: IV) :: Nil => true; case _ => false }} || newLBs.forall(_.isSmall))) {
196+
if isPos && !isNeg && ({newLBs match { case (tv: IV) :: Nil => true; case _ => false }} || newLBs.forall(_ => true)) then {
197+
// if (isPos && !isNeg && ({newLBs match { case (tv: IV) :: Nil => true; case _ => false }})) {
198+
newLBs.foldLeft(Bot: Type)(_ | _)
199+
} else
200+
// if (isNeg && !isPos && (Analysis.occsNum(tv) === 1 && {newUBs match { case (tv: IV) :: Nil => true; case _ => false }} || newUBs.forall(_.isSmall))) {
201+
if isNeg && !isPos && ({newUBs match { case (tv: IV) :: Nil => true; case _ => false }} || newUBs.forall(_ => true)) then
202+
// if (isNeg && !isPos && ({newUBs match { case (tv: IV) :: Nil => true; case _ => false }})) {
203+
newUBs.foldLeft(Top: Type)(_ & _)
204+
else tv
203205
else
204206
// tv.lowerBounds = newLBs
205207
// tv.upperBounds = newUBs

hkmc2/shared/src/main/scala/hkmc2/bbml/types.scala

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -281,12 +281,39 @@ object Type:
281281
then lhs | rhs
282282
else lhs & rhs
283283
def mkNegType(ty: Type): Type = ty.!
284-
def disjoint(a:Type,b:Type):Opt[Ls[InfVar->BasicType]]=(a,b)match
285-
case (Bot,_)|(_,Bot)=>S(Nil)
286-
case (ClassLikeType(a,_),ClassLikeType(b,_))if a.uid=/=b.uid=>S(Nil)
287-
case (a:ClassLikeType,v:InfVar)=>S(Ls(v->a))
288-
case (v:InfVar,a:ClassLikeType)=>S(Ls(v->a))
289-
case _=>N
284+
def disjoint(a: BasicType, b: BasicType)(prev: Set[BasicType -> BasicType])
285+
(using c: MutMap[BasicType -> BasicType, Opt[Set[Set[InfVar->BasicType]]]])
286+
: Opt[Set[Set[InfVar->BasicType]]] =
287+
if !prev.contains(a -> b) then c.getOrElseUpdate(a -> b, {
288+
(a, b) match
289+
case (Bot, _) | (_, Bot) => S(Set.empty)
290+
case (NegType(t),_) => t.toBasic.!.simp.toBasic match
291+
case NegType(_) => N
292+
case a => disjoint(a, b)(prev)
293+
case (_, NegType(t)) => t.toBasic.!.simp.toBasic match
294+
case NegType(_) => N
295+
case a => disjoint(a, b)(prev)
296+
case (ClassLikeType(a, _), ClassLikeType(b, _)) if a.uid =/= b.uid => S(Set.empty)
297+
case (ComposedType(p, q, true), _) =>
298+
val u = disjoint(p.toBasic.simp.toBasic, b)(prev)
299+
val w = disjoint(q.toBasic.simp.toBasic, b)(prev)
300+
u.flatMap(u => w.map(u ++ _))
301+
case (_, ComposedType(p, q, true)) =>
302+
val u = disjoint(a, p.toBasic.simp.toBasic)(prev)
303+
val w = disjoint(a, q.toBasic.simp.toBasic)(prev)
304+
u.flatMap(u => w.map(u ++ _))
305+
case (a: InfVar, b: InfVar) if a.uid =/= b.uid => N
306+
case (v: InfVar, _) =>
307+
val p = prev + (v->b)
308+
val k = v.state.lowerBounds.map(lb => disjoint(lb.toBasic.simp.toBasic, b)(p))
309+
if k.exists(_.isEmpty) then N
310+
else
311+
val u = (k.flatten.flatten.toSet + Set.empty).map(_ + (v -> b))
312+
val w = v.state.upperBounds.flatMap(ub => disjoint(ub.toBasic.simp.toBasic, b)(p))
313+
S(w.fold(u)((x, y) => y.flatMap(y => x.map(_ ++ y))))
314+
case (_, v: InfVar) => disjoint(v, a)(prev)
315+
case _ => N
316+
}) else N
290317

291318

292319
// * Poly types can not be used as type arguments
@@ -396,9 +423,10 @@ class VarState:
396423
var lowerBounds: Ls[Type] = Nil
397424
var upperBounds: Ls[Type] = Nil
398425
val disjsub: MutSet[DisjSub] = MutSet.empty
426+
override def toString = "<>"
399427

400-
case class DisjSub(disjoint:MutMap[InfVar,BasicType],dss:Ls[DisjSub],cs:Ls[Type->Type]):
401-
def commit()=disjoint.keys.foreach(_.state.disjsub+=this)
428+
case class DisjSub(disjoint: MutMap[InfVar,BasicType], dss:Ls[DisjSub], cs:Ls[Type->Type]):
429+
def commit() = disjoint.keys.foreach(_.state.disjsub += this)
402430
def remove(v:InfVar)=
403431
v.state.disjsub-=this
404432
disjoint-=v

hkmc2/shared/src/test/mlscript/bbml/DisjSub.mls

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ idIB(true)
3030
idIB(if true then 1 else true)
3131
//│ Type: Bool ∨ Int
3232

33+
x=>
34+
let y = x+1
35+
idIB(x)
36+
//│ Type: ('x) ->{⊥} ⊥
37+
//│ Where:
38+
//│ 'x <: Int ∨ Bool
39+
//│ 'x <: Int
40+
//│ 'x#Int ∨ Int<:'app ∧ ⊥<:'eff}
3341

3442
fun ap1(f)=f(1)
3543
ap1(idIB)
@@ -40,23 +48,27 @@ ap(idIB)(1)
4048

4149
:todo
4250
x=>idIB(x)
43-
//│ Type: (Int ∨ Bool) ->{⊥} ⊥
51+
//│ Type: ('x) ->{⊥} ⊥
52+
//│ Where:
53+
//│ 'x <: Int ∨ Bool
54+
//│ 'x#Int ∨ Int<:'app ∧ ⊥<:'eff}
55+
//│ 'x#Bool ∨ Bool<:'app ∧ ⊥<:'eff}
4456

4557

4658
:todo // BbML
4759
fun idIIBB: ([Int, Int] -> Int) & ([Bool, Bool] -> Bool)
4860
//│ ╔══[ERROR] General type is not allowed here.
49-
//│ ║ l.47: fun idIIBB: ([Int, Int] -> Int) & ([Bool, Bool] -> Bool)
61+
//│ ║ l.59: fun idIIBB: ([Int, Int] -> Int) & ([Bool, Bool] -> Bool)
5062
//│ ╙── ^^^
5163
//│ ╔══[ERROR] General type is not allowed here.
52-
//│ ║ l.47: fun idIIBB: ([Int, Int] -> Int) & ([Bool, Bool] -> Bool)
64+
//│ ║ l.59: fun idIIBB: ([Int, Int] -> Int) & ([Bool, Bool] -> Bool)
5365
//│ ╙── ^^^^
5466
//│ Type: ⊤
5567

5668
:todo // BbML
5769
idIIBB([1, 2])
5870
//│ ╔══[ERROR] Term shape not yet supported by BbML: Tup(List(Fld(‹›,Lit(IntLit(1)),None), Fld(‹›,Lit(IntLit(2)),None)))
59-
//│ ║ l.57: idIIBB([1, 2])
71+
//│ ║ l.69: idIIBB([1, 2])
6072
//│ ╙── ^^^^^^
6173
//│ Type: ⊥
6274

@@ -86,7 +98,7 @@ idIIBB(new Pair(1, true))
8698
:todo
8799
fun foo: ["x": Int, "y": Int]
88100
//│ ╔══[ERROR] Invalid type
89-
//│ ║ l.87: fun foo: ["x": Int, "y": Int]
101+
//│ ║ l.99: fun foo: ["x": Int, "y": Int]
90102
//│ ╙── ^^^^^^^^^^^^^^^^^^^^
91103
//│ Type: ⊤
92104

hkmc2/shared/src/test/mlscript/bbml/bbBasics.mls

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ fun foofoo(x) =
152152
new Printer(foofoo)
153153
//│ Type: Printer['T]
154154
//│ Where:
155-
//│ 'T <: Int
155+
//│ 'T#'T ∨ Str<:Str ∧ ⊥<:⊥ ∧ 'T<:'x}
156156

157157
let ip = new Printer(foofoo) in ip.Printer#f(42)
158158
//│ Type: Str
@@ -166,6 +166,10 @@ let ip = new Printer(foofoo) in ip.Printer#f("42")
166166
//│ ╟── because: cannot constrain Str <: 'T
167167
//│ ╟── because: cannot constrain Str <: ¬(¬'T)
168168
//│ ╟── because: cannot constrain Str <: 'T
169+
//│ ╟── because: cannot constrain 'T <: 'x
170+
//│ ╟── because: cannot constrain 'T <: 'x
171+
//│ ╟── because: cannot constrain 'T <: ¬¬Int
172+
//│ ╟── because: cannot constrain 'T <: ¬(¬{Int})
169173
//│ ╙── because: cannot constrain Str <: ¬(¬{Int})
170174
//│ Type: Str
171175

@@ -178,23 +182,26 @@ fun inc(x) = x + 1
178182
new TFun(inc)
179183
//│ Type: TFun['T]
180184
//│ Where:
181-
//│ Int <: 'T
182-
//│ 'T <: Int
185+
//│ 'T#'T ∨ Int<:'T ∧ ⊥<:⊥ ∧ 'T<:'x}
183186

184187
let tf = new TFun(inc) in tf.TFun#f(1)
185188
//│ Type: Int
186189

187190
:e
188191
let tf = new TFun(inc) in tf.TFun#f("1")
189192
//│ ╔══[ERROR] Type error in string literal with expected type 'T
190-
//│ ║ l.188: let tf = new TFun(inc) in tf.TFun#f("1")
193+
//│ ║ l.191: let tf = new TFun(inc) in tf.TFun#f("1")
191194
//│ ║ ^^^
192195
//│ ╟── because: cannot constrain Str <: 'T
193196
//│ ╟── because: cannot constrain Str <: 'T
194197
//│ ╟── because: cannot constrain Str <: ¬(¬'T)
195198
//│ ╟── because: cannot constrain Str <: 'T
199+
//│ ╟── because: cannot constrain 'T <: 'x
200+
//│ ╟── because: cannot constrain 'T <: 'x
201+
//│ ╟── because: cannot constrain 'T <: ¬¬Int
202+
//│ ╟── because: cannot constrain 'T <: ¬(¬{Int})
196203
//│ ╙── because: cannot constrain Str <: ¬(¬{Int})
197-
//│ Type: StrInt
204+
//│ Type: IntStr
198205

199206
class Pair[A, B](fst: A, snd: B)
200207
//│ Type: ⊤
@@ -296,6 +303,8 @@ f
296303

297304
f(x => x).Foo#x
298305
//│ Type: ('A) ->{⊥} 'A
306+
//│ Where:
307+
//│ 'A#'A ∨ 'x<:'A ∧ ⊥<:⊥ ∧ 'A<:'x}
299308

300309
g => (new Foo(g)).Foo#x
301310
//│ Type: ('A -> 'A) ->{⊥} ('A) ->{⊥} 'A
@@ -308,7 +317,7 @@ throw new Error("oops")
308317
:e
309318
throw 42
310319
//│ ╔══[ERROR] Type error in throw
311-
//│ ║ l.309: throw 42
320+
//│ ║ l.318: throw 42
312321
//│ ║ ^^
313322
//│ ╙── because: cannot constrain Int <: Error
314323
//│ Type: ⊥

hkmc2/shared/src/test/mlscript/bbml/bbBounds.mls

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ bazbaz
8787
//│ Type: ['A] -> ('A) ->{⊥} ('A -> 'A) ->{⊥} 'A
8888
//│ Where:
8989
//│ 'A <: Int
90+
//│ 'A#Int ∨ 'A<:'A ∧ ⊥<:⊥ ∧ 'A<:'A}
9091

9192
bazbaz(42)(x => x + 1)
9293
//│ Type: Int
@@ -97,6 +98,7 @@ cc
9798
//│ Where:
9899
//│ 'A -> 'A <: 'B
99100
//│ 'B <: 'A -> 'A
101+
//│ 'B#'B ∨ 'B<:'B ∧ ⊥<:⊥ ∧ 'B<:'B}
100102
//│ 'B -> 'B <: 'A
101103
//│ 'A <: 'B -> 'B
102104

@@ -112,17 +114,19 @@ fun h: [C] -> ([A extends Int] -> A -> ([B extends A -> A restricts A -> A] -> B
112114
:e
113115
bazbaz: [A extends Int] -> A -> ([B extends A -> A restricts A -> A] -> B) -> A
114116
//│ ╔══[ERROR] Cannot type non-function term Ref(member:bazbaz) as (A) ->{⊥} ([outer, 'B] -> 'B) ->{⊥} A
115-
//│ ║ l.113: bazbaz: [A extends Int] -> A -> ([B extends A -> A restricts A -> A] -> B) -> A
117+
//│ ║ l.115: bazbaz: [A extends Int] -> A -> ([B extends A -> A restricts A -> A] -> B) -> A
116118
//│ ╙── ^^^^^^
117119
//│ Type: ['A] -> ('A) ->{⊥} ('A -> 'A) ->{⊥} 'A
118120
//│ Where:
119121
//│ 'A <: Int
122+
//│ 'A#Int ∨ 'A<:'A ∧ ⊥<:⊥ ∧ 'A<:'A}
120123

121124

122125
(x => f => bazbaz(x)(f)): [A extends Int] -> A -> ([B extends A -> A restricts A -> A] -> B) -> A
123126
//│ Type: ['A] -> ('A) ->{⊥} ('A -> 'A) ->{⊥} 'A
124127
//│ Where:
125128
//│ 'A <: Int
129+
//│ 'A#Int ∨ 'A<:'A ∧ ⊥<:⊥ ∧ 'A<:'A}
126130

127131

128132
h(x => f => bazbaz(x)(f))(42)

hkmc2/shared/src/test/mlscript/bbml/bbCyclicExtrude.mls

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,8 @@ let foo = f => (x => f(x(x)) : [A] -> A -> A) in foo
1818
f => (let g = x => x(x) in f(g(g))) : [A] -> A -> A
1919
//│ Type: (⊥ -> (⊤ -> ⊥)) ->{⊥} ['A] -> ('A) ->{⊥} 'A
2020

21-
:e
2221
f => (let g = x => f(x(x)) in g) : [A] -> A -> A
23-
//│ ╔══[ERROR] Type error in block with expected type (A) ->{⊥} A
24-
//│ ║ l.22: f => (let g = x => f(x(x)) in g) : [A] -> A -> A
25-
//│ ║ ^^^^^^^^^^^^^^^^^
26-
//│ ╟── because: cannot constrain 'x ->{'eff ∨ 'eff1} 'app <: A -> A
27-
//│ ╟── because: cannot constrain A <: 'x
28-
//│ ╟── because: cannot constrain A <: 'x
29-
//│ ╙── because: cannot constrain A <: ¬(¬{'x ->{'eff1} 'app1})
30-
//│ Type: (⊥ -> ⊥) ->{⊥} ['A] -> ('A) ->{⊥} 'A
22+
//│ Type: (⊥ ->{⊤} ⊤) ->{⊥} ['A] -> ('A) ->{⊥} 'A
3123

3224
f => (x => f(x(x)) : [A] -> A -> A)
3325
//│ Type: ('app -> (⊤ -> ⊥)) ->{⊥} ('x -> 'app) ->{⊥} ['A] -> ('A) ->{⊥} 'A
@@ -48,7 +40,7 @@ let foo(f) = (f(x => x(x)) : [A] -> A -> A) in foo
4840
:todo
4941
fun foo(f) = (f(x => x(x)) : [A] -> A -> A)
5042
//│ ╔══[ERROR] Expected a monomorphic type or an instantiable type here, but ('f) ->{⊥} [outer, 'A] -> ('A) ->{⊥} 'A found
51-
//│ ║ l.49: fun foo(f) = (f(x => x(x)) : [A] -> A -> A)
43+
//│ ║ l.42: fun foo(f) = (f(x => x(x)) : [A] -> A -> A)
5244
//│ ╙── ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5345
//│ Type: ⊤
5446

0 commit comments

Comments
 (0)