@@ -386,19 +386,15 @@ object Types {
386386
387387 /** The base classes of this type as determined by ClassDenotation
388388 * in linearization order, with the class itself as first element.
389- * For AndTypes/OrTypes, the union/intersection of the operands' baseclasses .
390- * Inherited by all type proxies. `Nil` for all other types.
389+ * Inherited by all type proxies. Overridden for And and Or types .
390+ * `Nil` for all other types.
391391 */
392- final def baseClasses (implicit ctx : Context ): List [ClassSymbol ] = track(" baseClasses" ) {
392+ def baseClasses (implicit ctx : Context ): List [ClassSymbol ] = track(" baseClasses" ) {
393393 this match {
394394 case tp : TypeProxy =>
395395 tp.underlying.baseClasses
396396 case tp : ClassInfo =>
397397 tp.cls.baseClasses
398- case AndType (tp1, tp2) =>
399- tp1.baseClasses union tp2.baseClasses
400- case OrType (tp1, tp2) =>
401- tp1.baseClasses intersect tp2.baseClasses
402398 case _ => Nil
403399 }
404400 }
@@ -474,22 +470,24 @@ object Types {
474470 */
475471 final def findMember (name : Name , pre : Type , excluded : FlagSet )(implicit ctx : Context ): Denotation = {
476472 @ tailrec def go (tp : Type ): Denotation = tp match {
477- case tp : RefinedType =>
478- if (name eq tp.refinedName) goRefined(tp) else go(tp.parent)
479- case tp : ThisType =>
480- goThis(tp)
481- case tp : TypeRef =>
482- tp.denot.findMember(name, pre, excluded)
483473 case tp : TermRef =>
484474 go (tp.underlying match {
485475 case mt : MethodType
486476 if mt.paramInfos.isEmpty && (tp.symbol is Stable ) => mt.resultType
487477 case tp1 => tp1
488478 })
489- case tp : TypeParamRef =>
490- goParam(tp)
479+ case tp : TypeRef =>
480+ tp.denot.findMember(name, pre, excluded)
481+ case tp : ThisType =>
482+ goThis(tp)
483+ case tp : RefinedType =>
484+ if (name eq tp.refinedName) goRefined(tp) else go(tp.parent)
491485 case tp : RecType =>
492486 goRec(tp)
487+ case tp : TypeParamRef =>
488+ goParam(tp)
489+ case tp : SuperType =>
490+ goSuper(tp)
493491 case tp : HKApply =>
494492 goApply(tp)
495493 case tp : TypeProxy =>
@@ -613,6 +611,12 @@ object Types {
613611 go(next)
614612 }
615613 }
614+ def goSuper (tp : SuperType ) = go(tp.underlying) match {
615+ case d : JointRefDenotation =>
616+ typr.println(i " redirecting super. $name from $tp to ${d.symbol.showLocated}" )
617+ new UniqueRefDenotation (d.symbol, tp.memberInfo(d.symbol), d.validFor)
618+ case d => d
619+ }
616620 def goAnd (l : Type , r : Type ) = {
617621 go(l) & (go(r), pre, safeIntersection = ctx.pendingMemberSearches.contains(name))
618622 }
@@ -2298,6 +2302,37 @@ object Types {
22982302 def tp2 : Type
22992303 def isAnd : Boolean
23002304 def derivedAndOrType (tp1 : Type , tp2 : Type )(implicit ctx : Context ): Type // needed?
2305+
2306+ private [this ] var myBaseClassesPeriod : Period = Nowhere
2307+ private [this ] var myBaseClasses : List [ClassSymbol ] = _
2308+
2309+ /** Base classes of And are the merge of the operand base classes
2310+ * For OrTypes, it's the intersection.
2311+ */
2312+ override final def baseClasses (implicit ctx : Context ) = {
2313+ if (myBaseClassesPeriod != ctx.period) {
2314+ val bcs1 = tp1.baseClasses
2315+ val bcs1set = BaseClassSet (bcs1)
2316+ def recur (bcs2 : List [ClassSymbol ]): List [ClassSymbol ] = bcs2 match {
2317+ case bc2 :: bcs2rest =>
2318+ if (isAnd)
2319+ if (bcs1set contains bc2)
2320+ if (bc2.is(Trait )) recur(bcs2rest)
2321+ else bcs1 // common class, therefore rest is the same in both sequences
2322+ else bc2 :: recur(bcs2rest)
2323+ else
2324+ if (bcs1set contains bc2)
2325+ if (bc2.is(Trait )) bc2 :: recur(bcs2rest)
2326+ else bcs2
2327+ else recur(bcs2rest)
2328+ case nil =>
2329+ if (isAnd) bcs1 else bcs2
2330+ }
2331+ myBaseClasses = recur(tp2.baseClasses)
2332+ myBaseClassesPeriod = ctx.period
2333+ }
2334+ myBaseClasses
2335+ }
23012336 }
23022337
23032338 abstract case class AndType (tp1 : Type , tp2 : Type ) extends CachedGroundType with AndOrType {
0 commit comments