@@ -205,12 +205,6 @@ object Types {
205
205
false
206
206
}
207
207
208
- /** Like isRef, but also extends to unions and intersections */
209
- def isCombinedRef (sym : Symbol )(using Context ): Boolean = stripped match
210
- case AndType (tp1 : Type , tp2 : Type ) => tp1.isRef(sym) || tp2.isRef(sym)
211
- case OrType (tp1 : Type , tp2 : Type ) => tp1.isRef(sym) && tp2.isRef(sym)
212
- case _ => isRef(sym)
213
-
214
208
def isAny (using Context ): Boolean = isRef(defn.AnyClass , skipRefined = false )
215
209
def isAnyRef (using Context ): Boolean = isRef(defn.ObjectClass , skipRefined = false )
216
210
def isAnyKind (using Context ): Boolean = isRef(defn.AnyKindClass , skipRefined = false )
@@ -230,7 +224,9 @@ object Types {
230
224
case _ => false
231
225
}
232
226
233
- /** Is this type an instance of a non-bottom subclass of the given class `cls`? */
227
+ /** True if this type is an instance of the given `cls` or an instance of
228
+ * a non-bottom subclass of `cls`.
229
+ */
234
230
final def derivesFrom (cls : Symbol )(using Context ): Boolean = {
235
231
def loop (tp : Type ): Boolean = tp match {
236
232
case tp : TypeRef =>
@@ -245,11 +241,15 @@ object Types {
245
241
case tp : AndType =>
246
242
loop(tp.tp1) || loop(tp.tp2)
247
243
case tp : OrType =>
248
- // If the type is `T | Null` or `T | Nothing`, and `T` derivesFrom the class,
249
- // then the OrType derivesFrom the class. Otherwise, we need to check both sides
250
- // derivesFrom the class.
251
- loop(tp.tp1) && (loop(tp.tp2) || defn.isBottomType(tp.tp2))
252
- || defn.isBottomType(tp.tp1) && loop(tp.tp2)
244
+ // If the type is `T | Null` or `T | Nothing`, the class is != Nothing,
245
+ // and `T` derivesFrom the class, then the OrType derivesFrom the class.
246
+ // Otherwise, we need to check both sides derivesFrom the class.
247
+ if defn.isBottomType(tp.tp1) && cls != defn.NothingClass then
248
+ loop(tp.tp2)
249
+ else if defn.isBottomType(tp.tp2) && cls != defn.NothingClass then
250
+ loop(tp.tp1)
251
+ else
252
+ loop(tp.tp1) && loop(tp.tp2)
253
253
case tp : JavaArrayType =>
254
254
cls == defn.ObjectClass
255
255
case _ =>
@@ -484,6 +484,22 @@ object Types {
484
484
final def classSymbols (using Context ): List [ClassSymbol ] =
485
485
parentSymbols(_.isClass).asInstanceOf
486
486
487
+ /** Same as `this.classSymbols.contains(cls)` but more efficient */
488
+ final def hasClassSymbol (cls : Symbol )(using Context ): Boolean = this match
489
+ case tp : TypeRef =>
490
+ val sym = tp.symbol
491
+ sym == cls || ! sym.isClass && tp.superType.hasClassSymbol(cls)
492
+ case tp : TypeProxy =>
493
+ tp.underlying.hasClassSymbol(cls)
494
+ case tp : ClassInfo =>
495
+ tp.cls == cls
496
+ case AndType (l, r) =>
497
+ l.hasClassSymbol(cls) || r.hasClassSymbol(cls)
498
+ case OrType (l, r) =>
499
+ l.hasClassSymbol(cls) && r.hasClassSymbol(cls)
500
+ case _ =>
501
+ false
502
+
487
503
/** The term symbol associated with the type */
488
504
@ tailrec final def termSymbol (using Context ): Symbol = this match {
489
505
case tp : TermRef => tp.symbol
0 commit comments