@@ -103,6 +103,9 @@ class TypeComparer(initctx: Context) extends ConstraintHandling {
103
103
true
104
104
}
105
105
106
+ protected def gadtBounds (sym : Symbol )(implicit ctx : Context ) = ctx.gadt.bounds(sym)
107
+ protected def gadtSetBounds (sym : Symbol , b : TypeBounds ) = ctx.gadt.setBounds(sym, b)
108
+
106
109
// Subtype testing `<:<`
107
110
108
111
def topLevelSubType (tp1 : Type , tp2 : Type ): Boolean = {
@@ -375,7 +378,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling {
375
378
def thirdTryNamed (tp2 : NamedType ): Boolean = tp2.info match {
376
379
case info2 : TypeBounds =>
377
380
def compareGADT : Boolean = {
378
- val gbounds2 = ctx.gadt.bounds (tp2.symbol)
381
+ val gbounds2 = gadtBounds (tp2.symbol)
379
382
(gbounds2 != null ) &&
380
383
(isSubTypeWhenFrozen(tp1, gbounds2.lo) ||
381
384
narrowGADTBounds(tp2, tp1, approx, isUpper = false )) &&
@@ -601,7 +604,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling {
601
604
tp1.info match {
602
605
case TypeBounds (_, hi1) =>
603
606
def compareGADT = {
604
- val gbounds1 = ctx.gadt.bounds (tp1.symbol)
607
+ val gbounds1 = gadtBounds (tp1.symbol)
605
608
(gbounds1 != null ) &&
606
609
(isSubTypeWhenFrozen(gbounds1.hi, tp2) ||
607
610
narrowGADTBounds(tp1, tp2, approx, isUpper = true )) &&
@@ -1146,12 +1149,12 @@ class TypeComparer(initctx: Context) extends ConstraintHandling {
1146
1149
gadts.println(i " narrow gadt bound of $tparam: ${tparam.info} from ${if (isUpper) " above" else " below" } to $bound ${bound.toString} ${bound.isRef(tparam)}" )
1147
1150
if (bound.isRef(tparam)) false
1148
1151
else {
1149
- val oldBounds = ctx.gadt.bounds (tparam)
1152
+ val oldBounds = gadtBounds (tparam)
1150
1153
val newBounds =
1151
1154
if (isUpper) TypeBounds (oldBounds.lo, oldBounds.hi & bound)
1152
1155
else TypeBounds (oldBounds.lo | bound, oldBounds.hi)
1153
1156
isSubType(newBounds.lo, newBounds.hi) &&
1154
- { ctx.gadt.setBounds (tparam, newBounds); true }
1157
+ { gadtSetBounds (tparam, newBounds); true }
1155
1158
}
1156
1159
}
1157
1160
}
@@ -1737,11 +1740,33 @@ object TypeComparer {
1737
1740
class TrackingTypeComparer (initctx : Context ) extends TypeComparer (initctx) {
1738
1741
import state .constraint
1739
1742
1743
+ val footprint = mutable.Set [Type ]()
1744
+
1745
+ override def bounds (param : TypeParamRef ): TypeBounds = {
1746
+ if (param.binder `ne` caseLambda) footprint += param
1747
+ super .bounds(param)
1748
+ }
1749
+
1750
+ override def addOneBound (param : TypeParamRef , bound : Type , isUpper : Boolean ): Boolean = {
1751
+ if (param.binder `ne` caseLambda) footprint += param
1752
+ super .addOneBound(param, bound, isUpper)
1753
+ }
1754
+
1755
+ override def gadtBounds (sym : Symbol )(implicit ctx : Context ) = {
1756
+ footprint += sym.typeRef
1757
+ super .gadtBounds(sym)
1758
+ }
1759
+
1760
+ override def gadtSetBounds (sym : Symbol , b : TypeBounds ) = {
1761
+ footprint += sym.typeRef
1762
+ super .gadtSetBounds(sym, b)
1763
+ }
1764
+
1740
1765
def matchCase (scrut : Type , cas : Type , instantiate : Boolean )(implicit ctx : Context ): Type = {
1741
1766
1742
1767
def paramInstances = new TypeAccumulator [Array [Type ]] {
1743
1768
def apply (inst : Array [Type ], t : Type ) = t match {
1744
- case t @ TypeParamRef (b, n) if b `eq` unfrozen =>
1769
+ case t @ TypeParamRef (b, n) if b `eq` caseLambda =>
1745
1770
inst(n) = instanceType(t, fromBelow = variance >= 0 )
1746
1771
inst
1747
1772
case _ =>
@@ -1751,7 +1776,7 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
1751
1776
1752
1777
def instantiateParams (inst : Array [Type ]) = new TypeMap {
1753
1778
def apply (t : Type ) = t match {
1754
- case t @ TypeParamRef (b, n) if b `eq` unfrozen => inst(n)
1779
+ case t @ TypeParamRef (b, n) if b `eq` caseLambda => inst(n)
1755
1780
case t : LazyRef => apply(t.ref)
1756
1781
case _ => mapOver(t)
1757
1782
}
@@ -1762,16 +1787,16 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
1762
1787
inFrozenConstraint {
1763
1788
val cas1 = cas match {
1764
1789
case cas : HKTypeLambda =>
1765
- unfrozen = constrained(cas)
1766
- unfrozen .resultType
1790
+ caseLambda = constrained(cas)
1791
+ caseLambda .resultType
1767
1792
case _ =>
1768
1793
cas
1769
1794
}
1770
1795
val defn .FunctionOf (pat :: Nil , body, _, _) = cas1
1771
1796
if (isSubType(scrut, pat))
1772
- unfrozen match {
1773
- case unfrozen : HKTypeLambda if instantiate =>
1774
- val instances = paramInstances(new Array (unfrozen .paramNames.length), pat)
1797
+ caseLambda match {
1798
+ case caseLambda : HKTypeLambda if instantiate =>
1799
+ val instances = paramInstances(new Array (caseLambda .paramNames.length), pat)
1775
1800
instantiateParams(instances)(body)
1776
1801
case _ =>
1777
1802
body
0 commit comments