@@ -32,6 +32,9 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
32
32
def constraint : Constraint = state.constraint
33
33
def constraint_= (c : Constraint ): Unit = state.constraint = c
34
34
35
+ override protected def typeLub (tp1 : Type , tp2 : Type )(implicit actx : AbsentContext ): Type =
36
+ lub(tp1, tp2)
37
+
35
38
private [this ] var pendingSubTypes : mutable.Set [(Type , Type )] = null
36
39
private [this ] var recCount = 0
37
40
private [this ] var monitored = false
@@ -1415,9 +1418,10 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
1415
1418
1416
1419
/** The least upper bound of two types
1417
1420
* @param canConstrain If true, new constraints might be added to simplify the lub.
1418
- * @note We do not admit singleton types in or-types as lubs.
1421
+ * @param admitSingletons We only admit singletons as parts of lubs when we must maintain necessary conditions,
1422
+ * such as when inferring GADT constraints.
1419
1423
*/
1420
- def lub (tp1 : Type , tp2 : Type , canConstrain : Boolean = false ): Type = /* >|>*/ trace(s " lub( ${tp1.show}, ${tp2.show}, canConstrain= $canConstrain) " , subtyping, show = true ) /* <|<*/ {
1424
+ def lub (tp1 : Type , tp2 : Type , canConstrain : Boolean = false , admitSingletons : Boolean = false ): Type = /* >|>*/ trace(s " lub( ${tp1.show}, ${tp2.show}, canConstrain= $canConstrain) " , subtyping, show = true ) /* <|<*/ {
1421
1425
if (tp1 eq tp2) tp1
1422
1426
else if (! tp1.exists) tp1
1423
1427
else if (! tp2.exists) tp2
@@ -1429,6 +1433,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
1429
1433
else {
1430
1434
val t2 = mergeIfSuper(tp2, tp1, canConstrain)
1431
1435
if (t2.exists) t2
1436
+ else if (admitSingletons) orType(tp1.widenExpr, tp2.widenExpr)
1432
1437
else {
1433
1438
val tp1w = tp1.widen
1434
1439
val tp2w = tp2.widen
@@ -1954,8 +1959,8 @@ class ExplainingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
1954
1959
super .hasMatchingMember(name, tp1, tp2)
1955
1960
}
1956
1961
1957
- override def lub (tp1 : Type , tp2 : Type , canConstrain : Boolean = false ): Type =
1958
- traceIndented(s " lub( ${show(tp1)}, ${show(tp2)}, canConstrain= $canConstrain) " ) {
1962
+ override def lub (tp1 : Type , tp2 : Type , canConstrain : Boolean = false , admitSingletons : Boolean = false ): Type =
1963
+ traceIndented(s " lub( ${show(tp1)}, ${show(tp2)}, canConstrain= $canConstrain, admitSingletons= $admitSingletons ) " ) {
1959
1964
super .lub(tp1, tp2, canConstrain)
1960
1965
}
1961
1966
0 commit comments