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