@@ -423,7 +423,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
423
423
(tp1.widenSingletons ne tp1) &&
424
424
recur(tp1.widenSingletons, tp2)
425
425
426
- if (tp2.atoms.nonEmpty)
426
+ if (tp2.atoms.nonEmpty && canCompare(tp2.atoms) )
427
427
tp1.atoms.nonEmpty && tp1.atoms.subsetOf(tp2.atoms)
428
428
else
429
429
widenOK || joinOK || recur(tp11, tp2) && recur(tp12, tp2)
@@ -581,7 +581,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
581
581
}
582
582
compareTypeLambda
583
583
case OrType (tp21, tp22) =>
584
- if (tp2.atoms.nonEmpty)
584
+ if (tp2.atoms.nonEmpty && canCompare(tp2.atoms) )
585
585
return tp1.atoms.nonEmpty && tp1.atoms.subsetOf(tp2.atoms) ||
586
586
tp1.isRef(NothingClass )
587
587
@@ -1064,6 +1064,23 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
1064
1064
else None
1065
1065
}
1066
1066
1067
+ /** Check whether we can compare the given set of atoms with another to determine
1068
+ * a subtype test between OrTypes. There is one situation where this is not
1069
+ * the case, which has to do with SkolemTypes. TreeChecker sometimes expects two
1070
+ * types to be equal that have different skolems. To account for this, we identify
1071
+ * two different skolems in all phases `p`, where `p.isTyper` is false.
1072
+ * But in that case comparing two sets of atoms that contain skolems
1073
+ * for equality would give the wrong result, so we should not use the sets
1074
+ * for comparisons.
1075
+ */
1076
+ def canCompare (atoms : Set [Type ]): Boolean =
1077
+ ctx.phase.isTyper || {
1078
+ val hasSkolems = new ExistsAccumulator (_.isInstanceOf [SkolemType ]) {
1079
+ override val stopAtStatic = true
1080
+ }
1081
+ ! atoms.exists(hasSkolems(false , _))
1082
+ }
1083
+
1067
1084
/** Subtype test for corresponding arguments in `args1`, `args2` according to
1068
1085
* variances in type parameters `tparams2`.
1069
1086
*
0 commit comments