@@ -384,7 +384,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
384
384
// So if the constraint is not yet frozen, we do the same comparison again
385
385
// with a frozen constraint, which means that we get a chance to do the
386
386
// widening in `fourthTry` before adding to the constraint.
387
- if (frozenConstraint || alwaysFluid ) isSubType(tp1, bounds(tp2).lo)
387
+ if (frozenConstraint) isSubType(tp1, bounds(tp2).lo)
388
388
else isSubTypeWhenFrozen(tp1, tp2)
389
389
alwaysTrue || {
390
390
if (canConstrain(tp2)) addConstraint(tp2, tp1.widenExpr, fromBelow = true )
@@ -1143,19 +1143,20 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
1143
1143
((defn.AnyType : Type ) /: tps)(glb)
1144
1144
1145
1145
/** The least upper bound of two types
1146
+ * @param canConstrain If true, new constraints might be added to simplify the lub.
1146
1147
* @note We do not admit singleton types in or-types as lubs.
1147
1148
*/
1148
- def lub (tp1 : Type , tp2 : Type ): Type = /* >|>*/ ctx.traceIndented(s " lub( ${tp1.show}, ${tp2.show}) " , subtyping, show = true ) /* <|<*/ {
1149
+ def lub (tp1 : Type , tp2 : Type , canConstrain : Boolean = false ): Type = /* >|>*/ ctx.traceIndented(s " lub( ${tp1.show}, ${tp2.show}, canConstrain= $canConstrain ) " , subtyping, show = true ) /* <|<*/ {
1149
1150
if (tp1 eq tp2) tp1
1150
1151
else if (! tp1.exists) tp1
1151
1152
else if (! tp2.exists) tp2
1152
1153
else if ((tp1 isRef AnyClass ) || (tp2 isRef NothingClass )) tp1
1153
1154
else if ((tp2 isRef AnyClass ) || (tp1 isRef NothingClass )) tp2
1154
1155
else {
1155
- val t1 = mergeIfSuper(tp1, tp2)
1156
+ val t1 = mergeIfSuper(tp1, tp2, canConstrain )
1156
1157
if (t1.exists) t1
1157
1158
else {
1158
- val t2 = mergeIfSuper(tp2, tp1)
1159
+ val t2 = mergeIfSuper(tp2, tp1, canConstrain )
1159
1160
if (t2.exists) t2
1160
1161
else {
1161
1162
val tp1w = tp1.widen
@@ -1169,7 +1170,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
1169
1170
1170
1171
/** The least upper bound of a list of types */
1171
1172
final def lub (tps : List [Type ]): Type =
1172
- ((defn.NothingType : Type ) /: tps)(lub)
1173
+ ((defn.NothingType : Type ) /: tps)(lub(_,_, canConstrain = false ) )
1173
1174
1174
1175
/** Merge `t1` into `tp2` if t1 is a subtype of some &-summand of tp2.
1175
1176
*/
@@ -1192,17 +1193,18 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
1192
1193
}
1193
1194
1194
1195
/** Merge `tp1` into `tp2` if tp1 is a supertype of some |-summand of tp2.
1196
+ * @param canConstrain If true, new constraints might be added to make the merge possible.
1195
1197
*/
1196
- private def mergeIfSuper (tp1 : Type , tp2 : Type ): Type =
1197
- if (isSubTypeWhenFrozen (tp2, tp1))
1198
- if (isSubTypeWhenFrozen (tp1, tp2)) tp2 else tp1 // keep existing type if possible
1198
+ private def mergeIfSuper (tp1 : Type , tp2 : Type , canConstrain : Boolean ): Type =
1199
+ if (isSubType (tp2, tp1, whenFrozen = ! canConstrain ))
1200
+ if (isSubType (tp1, tp2, whenFrozen = ! canConstrain )) tp2 else tp1 // keep existing type if possible
1199
1201
else tp2 match {
1200
1202
case tp2 @ OrType (tp21, tp22) =>
1201
- val higher1 = mergeIfSuper(tp1, tp21)
1203
+ val higher1 = mergeIfSuper(tp1, tp21, canConstrain )
1202
1204
if (higher1 eq tp21) tp2
1203
1205
else if (higher1.exists) higher1 | tp22
1204
1206
else {
1205
- val higher2 = mergeIfSuper(tp1, tp22)
1207
+ val higher2 = mergeIfSuper(tp1, tp22, canConstrain )
1206
1208
if (higher2 eq tp22) tp2
1207
1209
else if (higher2.exists) tp21 | higher2
1208
1210
else NoType
@@ -1491,9 +1493,9 @@ class ExplainingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
1491
1493
super .hasMatchingMember(name, tp1, tp2)
1492
1494
}
1493
1495
1494
- override def lub (tp1 : Type , tp2 : Type ) =
1495
- traceIndented(s " lub( ${show(tp1)}, ${show(tp2)}) " ) {
1496
- super .lub(tp1, tp2)
1496
+ override def lub (tp1 : Type , tp2 : Type , canConstrain : Boolean = false ) =
1497
+ traceIndented(s " lub( ${show(tp1)}, ${show(tp2)}, canConstrain= $canConstrain ) " ) {
1498
+ super .lub(tp1, tp2, canConstrain )
1497
1499
}
1498
1500
1499
1501
override def glb (tp1 : Type , tp2 : Type ) =
0 commit comments