Skip to content

Commit 8c0203b

Browse files
Cache myReduced = NoType if match type reduction overflowed (#20214)
2 parents 95a8a9c + 66f7f95 commit 8c0203b

File tree

1 file changed

+23
-25
lines changed

1 file changed

+23
-25
lines changed

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5100,7 +5100,7 @@ object Types extends TypeUtils {
51005100
def underlying(using Context): Type = bound
51015101

51025102
private var myReduced: Type | Null = null
5103-
private var reductionContext: util.MutableMap[Type, Type] = uninitialized
5103+
private var reductionContext: util.MutableMap[Type, Type] | Null = null
51045104

51055105
override def tryNormalize(using Context): Type =
51065106
try
@@ -5125,10 +5125,6 @@ object Types extends TypeUtils {
51255125
tp.underlying
51265126
}
51275127

5128-
def isUpToDate: Boolean =
5129-
reductionContext.keysIterator.forall: tp =>
5130-
reductionContext(tp) `eq` contextInfo(tp)
5131-
51325128
def setReductionContext(): Unit =
51335129
new TypeTraverser:
51345130
var footprint: Set[Type] = Set()
@@ -5159,44 +5155,46 @@ object Types extends TypeUtils {
51595155
cases.foreach(traverse)
51605156
reductionContext = util.HashMap()
51615157
for tp <- footprint do
5162-
reductionContext(tp) = contextInfo(tp)
5158+
reductionContext.nn(tp) = contextInfo(tp)
51635159
matchTypes.println(i"footprint for $thisMatchType $hashCode: ${footprint.toList.map(x => (x, contextInfo(x)))}%, %")
51645160
end setReductionContext
51655161

5162+
def changedReductionContext(): Boolean =
5163+
val isUpToDate = reductionContext != null && reductionContext.nn.iterator.forall(contextInfo(_) `eq` _)
5164+
if !isUpToDate then setReductionContext()
5165+
!isUpToDate
5166+
51665167
record("MatchType.reduce called")
51675168
if !Config.cacheMatchReduced
51685169
|| myReduced == null
5169-
|| !isUpToDate
5170+
|| changedReductionContext()
51705171
|| MatchTypeTrace.isRecording
51715172
then
51725173
record("MatchType.reduce computed")
51735174
if (myReduced != null) record("MatchType.reduce cache miss")
5174-
myReduced =
5175-
trace(i"reduce match type $this $hashCode", matchTypes, show = true):
5175+
val saved = ctx.typerState.snapshot()
5176+
try
5177+
myReduced = trace(i"reduce match type $this $hashCode", matchTypes, show = true):
51765178
withMode(Mode.Type):
5177-
setReductionContext()
5178-
def matchCases(cmp: MatchReducer): Type =
5179-
val saved = ctx.typerState.snapshot()
5180-
try
5181-
cmp.matchCases(scrutinee.normalized, cases.map(MatchTypeCaseSpec.analyze(_)))
5182-
catch case ex: Throwable =>
5183-
handleRecursive("reduce type ", i"$scrutinee match ...", ex)
5184-
finally
5185-
ctx.typerState.resetTo(saved)
5186-
// this drops caseLambdas in constraint and undoes any typevar
5187-
// instantiations during matchtype reduction
5188-
TypeComparer.reduceMatchWith(matchCases)
5179+
TypeComparer.reduceMatchWith: cmp =>
5180+
cmp.matchCases(scrutinee.normalized, cases.map(MatchTypeCaseSpec.analyze))
5181+
catch case ex: Throwable =>
5182+
myReduced = NoType
5183+
handleRecursive("reduce type ", i"$scrutinee match ...", ex)
5184+
finally
5185+
ctx.typerState.resetTo(saved)
5186+
// this drops caseLambdas in constraint and undoes any typevar
5187+
// instantiations during matchtype reduction
51895188

51905189
//else println(i"no change for $this $hashCode / $myReduced")
51915190
myReduced.nn
51925191
}
51935192

51945193
/** True if the reduction uses GADT constraints. */
51955194
def reducesUsingGadt(using Context): Boolean =
5196-
(reductionContext ne null) && reductionContext.keysIterator.exists {
5197-
case tp: TypeRef => reductionContext(tp).exists
5198-
case _ => false
5199-
}
5195+
reductionContext != null && reductionContext.nn.iterator.exists:
5196+
case (tp: TypeRef, tpCtx) => tpCtx.exists
5197+
case _ => false
52005198

52015199
override def computeHash(bs: Binders): Int = doHash(bs, scrutinee, bound :: cases)
52025200

0 commit comments

Comments
 (0)