@@ -225,16 +225,18 @@ object TypeOps:
225
225
*/
226
226
def orDominator (tp : Type )(using Context ): Type = {
227
227
228
- /** a faster version of cs1 intersect cs2 that treats bottom types correctly */
228
+ /** a faster version of cs1 intersect cs2 */
229
229
def intersect (cs1 : List [ClassSymbol ], cs2 : List [ClassSymbol ]): List [ClassSymbol ] =
230
- if cs1.head == defn.NothingClass then cs2
231
- else if cs2.head == defn.NothingClass then cs1
232
- else if cs1.head == defn.NullClass && ! ctx.explicitNulls && cs2.head.derivesFrom(defn.ObjectClass ) then cs2
233
- else if cs2.head == defn.NullClass && ! ctx.explicitNulls && cs1.head.derivesFrom(defn.ObjectClass ) then cs1
234
- else
235
- val cs2AsSet = new util.HashSet [ClassSymbol ](128 )
236
- cs2.foreach(cs2AsSet += _)
237
- cs1.filter(cs2AsSet.contains)
230
+ val cs2AsSet = BaseClassSet (cs2)
231
+ cs1.filter(cs2AsSet.contains)
232
+
233
+ /** a version of Type#baseClasses that treats bottom types correctly */
234
+ def orBaseClasses (tp : Type ): List [ClassSymbol ] = tp.stripTypeVar match
235
+ case OrType (tp1, tp2) =>
236
+ if tp1.isBottomType && (tp1 frozen_<:< tp2) then orBaseClasses(tp2)
237
+ else if tp2.isBottomType && (tp2 frozen_<:< tp1) then orBaseClasses(tp1)
238
+ else intersect(orBaseClasses(tp1), orBaseClasses(tp2))
239
+ case _ => tp.baseClasses
238
240
239
241
/** The minimal set of classes in `cs` which derive all other classes in `cs` */
240
242
def dominators (cs : List [ClassSymbol ], accu : List [ClassSymbol ]): List [ClassSymbol ] = (cs : @ unchecked) match {
@@ -369,7 +371,7 @@ object TypeOps:
369
371
}
370
372
371
373
// Step 3: Intersect base classes of both sides
372
- val commonBaseClasses = tp.mapReduceOr(_.baseClasses)(intersect )
374
+ val commonBaseClasses = orBaseClasses(tp )
373
375
val doms = dominators(commonBaseClasses, Nil )
374
376
def baseTp (cls : ClassSymbol ): Type =
375
377
tp.baseType(cls).mapReduceOr(identity)(mergeRefinedOrApplied)
0 commit comments