@@ -35,8 +35,6 @@ import language.implicitConversions
35
35
36
36
object Types {
37
37
38
- private var recCount = 0 // used temporarily for debugging. TODO: remove
39
-
40
38
private var nextId = 0
41
39
42
40
/** The class of types.
@@ -417,9 +415,7 @@ object Types {
417
415
* as seen from given prefix `pre`. Exclude all members that have
418
416
* flags in `excluded` from consideration.
419
417
*/
420
- final def findMember (name : Name , pre : Type , excluded : FlagSet )(implicit ctx : Context ): Denotation = try {
421
- recCount += 1
422
- assert(recCount < 40 )
418
+ final def findMember (name : Name , pre : Type , excluded : FlagSet )(implicit ctx : Context ): Denotation = {
423
419
@ tailrec def go (tp : Type ): Denotation = tp match {
424
420
case tp : RefinedType =>
425
421
if (name eq tp.refinedName) goRefined(tp) else go(tp.parent)
@@ -456,7 +452,11 @@ object Types {
456
452
if (tp.refinementRefersToThis) tp.refinedInfo.substSkolem(tp, pre)
457
453
else tp.refinedInfo
458
454
if (name.isTypeName) { // simplified case that runs more efficiently
459
- val jointInfo = if (rinfo.isAlias) rinfo else pdenot.info & rinfo
455
+ val jointInfo =
456
+ if (rinfo.isAlias) rinfo
457
+ else if (pdenot.info.isAlias) pdenot.info
458
+ else if (ctx.typeComparer.pendingMemberSearches.contains(name)) safeAnd(pdenot.info, rinfo)
459
+ else pdenot.info & rinfo
460
460
pdenot.asSingleDenotation.derivedSingleDenotation(pdenot.symbol, jointInfo)
461
461
} else
462
462
pdenot & (new JointRefDenotation (NoSymbol , rinfo, Period .allInRun(ctx.runId)), pre)
@@ -488,15 +488,30 @@ object Types {
488
488
}
489
489
def goAnd (l : Type , r : Type ) = go(l) & (go(r), pre)
490
490
def goOr (l : Type , r : Type ) = go(l) | (go(r), pre)
491
- go(this )
492
- } catch {
493
- case ex : MergeError =>
494
- throw new MergeError (s " ${ex.getMessage} as members of type ${pre.show}" )
495
- case ex : Throwable =>
496
- println(s " findMember exception for $this member $name" )
497
- throw ex // DEBUG
498
- } finally {
499
- recCount -= 1
491
+ def safeAnd (tp1 : Type , tp2 : Type ): Type = (tp1, tp2) match {
492
+ case (TypeBounds (lo1, hi1), TypeBounds (lo2, hi2)) => TypeBounds (lo1 | lo2, AndType (hi1, hi2))
493
+ case _ => tp1 & tp2
494
+ }
495
+
496
+ val cmp = ctx.typeComparer
497
+ val recCount = cmp.findMemberCount
498
+ cmp.findMemberCount = recCount + 1
499
+ if (recCount >= Config .LogPendingFindMemberThreshold ) {
500
+ cmp.pendingMemberSearches = name :: cmp.pendingMemberSearches
501
+ }
502
+ try go(this )
503
+ catch {
504
+ case ex : MergeError =>
505
+ throw new MergeError (s " ${ex.getMessage} as members of type ${pre.show}" )
506
+ case ex : Throwable =>
507
+ println(i " findMember exception for $this member $name" )
508
+ throw ex // DEBUG
509
+ }
510
+ finally {
511
+ cmp.findMemberCount = recCount - 1
512
+ if (recCount >= Config .LogPendingFindMemberThreshold )
513
+ cmp.pendingMemberSearches = cmp.pendingMemberSearches.tail
514
+ }
500
515
}
501
516
502
517
/** The set of names of members of this type that pass the given name filter
0 commit comments