@@ -1189,6 +1189,26 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
1189
1189
isSubRef(tp1, tp2) && isSubRef(tp2, tp1)
1190
1190
}
1191
1191
1192
+ /** If the range `tp1..tp2` consist of a single type, that type, otherwise NoType`.
1193
+ * This is the case if `tp1 =:= tp2`, but also if `tp1 <:< tp2`, `tp1` is a singleton type,
1194
+ * and `tp2` derives from `scala.Singleton` (or vice-versa). Examples of the latter case:
1195
+ *
1196
+ * "name".type .. Singleton
1197
+ * "name".type .. String & Singleton
1198
+ * Singleton .. "name".type
1199
+ * String & Singleton .. "name".type
1200
+ *
1201
+ * All consist of the single type `"name".type`.
1202
+ */
1203
+ def singletonInterval (tp1 : Type , tp2 : Type ): Type = {
1204
+ def isSingletonBounds (lo : Type , hi : Type ) =
1205
+ lo.isSingleton && hi.derivesFrom(defn.SingletonClass ) && isSubTypeWhenFrozen(lo, hi)
1206
+ if (isSameTypeWhenFrozen(tp1, tp2)) tp1
1207
+ else if (isSingletonBounds(tp1, tp2)) tp1
1208
+ else if (isSingletonBounds(tp2, tp1)) tp2
1209
+ else NoType
1210
+ }
1211
+
1192
1212
/** The greatest lower bound of two types */
1193
1213
def glb (tp1 : Type , tp2 : Type ): Type = /* >|>*/ trace(s " glb( ${tp1.show}, ${tp2.show}) " , subtyping, show = true ) /* <|<*/ {
1194
1214
if (tp1 eq tp2) tp1
@@ -1277,9 +1297,10 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
1277
1297
case tparam :: tparamsRest =>
1278
1298
val arg1 :: args1Rest = args1
1279
1299
val arg2 :: args2Rest = args2
1300
+ val common = singletonInterval(arg1, arg2)
1280
1301
val v = tparam.paramVariance
1281
1302
val lubArg =
1282
- if (isSameTypeWhenFrozen(arg1, arg2)) arg1
1303
+ if (common.exists) common
1283
1304
else if (v > 0 ) lub(arg1.hiBound, arg2.hiBound, canConstrain)
1284
1305
else if (v < 0 ) glb(arg1.loBound, arg2.loBound)
1285
1306
else TypeBounds (glb(arg1.loBound, arg2.loBound),
@@ -1308,9 +1329,10 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
1308
1329
case tparam :: tparamsRest =>
1309
1330
val arg1 :: args1Rest = args1
1310
1331
val arg2 :: args2Rest = args2
1332
+ val common = singletonInterval(arg1, arg2)
1311
1333
val v = tparam.paramVariance
1312
1334
val glbArg =
1313
- if (isSameTypeWhenFrozen(arg1, arg2)) arg1
1335
+ if (common.exists) common
1314
1336
else if (v > 0 ) glb(arg1.hiBound, arg2.hiBound)
1315
1337
else if (v < 0 ) lub(arg1.loBound, arg2.loBound)
1316
1338
else if (arg1.isInstanceOf [TypeBounds ] || arg2.isInstanceOf [TypeBounds ])
0 commit comments