Skip to content

Commit 46867c0

Browse files
authored
Fix #20521: Optimise caching for computing atoms and widened in OrTypes (#21223)
Fix #20521 When using the `atoms` of a large provisional union type, significant time is wasted computing the widened type and `lub` is invoked repeatedly. This PR addresses this issue by splitting the caching mechanisms for computing `atoms` and computing the widened type in `OrType`. As a result of this optimization, the compilation time for `tests/pos/i20521.scala` has been reduced from approximately 40 seconds to 6 seconds, making it comparable to Scala 2's performance.
2 parents c734d4e + ba0d8cb commit 46867c0

File tree

2 files changed

+805
-6
lines changed

2 files changed

+805
-6
lines changed

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

+5-6
Original file line numberDiff line numberDiff line change
@@ -3701,6 +3701,7 @@ object Types extends TypeUtils {
37013701
myUnion
37023702

37033703
private var atomsRunId: RunId = NoRunId
3704+
private var widenedRunId: RunId = NoRunId
37043705
private var myAtoms: Atoms = uninitialized
37053706
private var myWidened: Type = uninitialized
37063707

@@ -3716,20 +3717,18 @@ object Types extends TypeUtils {
37163717
val tp2w = tp2.widenSingletons()
37173718
if ((tp1 eq tp1w) && (tp2 eq tp2w)) this else TypeComparer.lub(tp1w, tp2w, isSoft = isSoft)
37183719

3719-
private def ensureAtomsComputed()(using Context): Unit =
3720+
override def atoms(using Context): Atoms =
37203721
if atomsRunId != ctx.runId then
37213722
myAtoms = computeAtoms()
3722-
myWidened = computeWidenSingletons()
37233723
if !isProvisional then atomsRunId = ctx.runId
3724-
3725-
override def atoms(using Context): Atoms =
3726-
ensureAtomsComputed()
37273724
myAtoms
37283725

37293726
override def widenSingletons(skipSoftUnions: Boolean)(using Context): Type =
37303727
if isSoft && skipSoftUnions then this
37313728
else
3732-
ensureAtomsComputed()
3729+
if widenedRunId != ctx.runId then
3730+
myWidened = computeWidenSingletons()
3731+
if !isProvisional then widenedRunId = ctx.runId
37333732
myWidened
37343733

37353734
def derivedOrType(tp1: Type, tp2: Type, soft: Boolean = isSoft)(using Context): Type =

0 commit comments

Comments
 (0)