Skip to content

Commit f64ce59

Browse files
committed
Add object TreeCache to Contextual.
1 parent 88e83f9 commit f64ce59

File tree

1 file changed

+33
-32
lines changed

1 file changed

+33
-32
lines changed

compiler/src/dotty/tools/dotc/transform/init/Semantic.scala

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ object Semantic:
378378
// ----- Checker State -----------------------------------
379379

380380
/** The state that threads through the interpreter */
381-
type Contextual[T] = (Context, Trace, Promoted, Cache.Data, Reporter) ?=> T
381+
type Contextual[T] = (Context, Trace, Promoted, Cache.Data, Reporter, TreeCache.CacheData) ?=> T
382382

383383
// ----- Error Handling -----------------------------------
384384

@@ -443,23 +443,29 @@ object Semantic:
443443

444444
inline def reporter(using r: Reporter): Reporter = r
445445

446-
// ----- Operations on trees -----------------------------
447-
val valOrDefDefRhs = mutable.Map[ValOrDefDef, Tree]()
448-
449-
extension (tree: ValOrDefDef)
450-
def getRhs(using Context): Tree =
451-
def getTree: Tree =
452-
val errorCount = ctx.reporter.errorCount
453-
val rhs = tree.rhs
454-
455-
if (ctx.reporter.errorCount > errorCount)
456-
report.warning("[Internal error] Ignoring analyses of " + tree.name + " due to error in reading TASTy. ")
457-
EmptyTree
458-
else
459-
rhs
460-
461-
valOrDefDefRhs.getOrElseUpdate(tree, getTree)
462-
446+
// ----- Cache for Trees -----------------------------
447+
448+
object TreeCache:
449+
class CacheData:
450+
private val emptyTrees = mutable.Set[ValOrDefDef]()
451+
452+
extension (tree: ValOrDefDef)
453+
def getRhs(using Context): Tree =
454+
def getTree: Tree =
455+
val errorCount = ctx.reporter.errorCount
456+
val rhs = tree.rhs
457+
458+
if (ctx.reporter.errorCount > errorCount)
459+
emptyTrees.add(tree)
460+
report.warning("Ignoring analyses of " + tree.name + " due to error in reading TASTy.")
461+
EmptyTree
462+
else
463+
rhs
464+
465+
if (emptyTrees.contains(tree)) EmptyTree
466+
else getTree
467+
end TreeCache
468+
463469
// ----- Operations on domains -----------------------------
464470
extension (a: Value)
465471
def join(b: Value): Value =
@@ -594,8 +600,7 @@ object Semantic:
594600
val target = if needResolve then resolve(ref.klass, field) else field
595601
if target.is(Flags.Lazy) then
596602
val rhs = target.defTree.asInstanceOf[ValDef].getRhs
597-
if rhs.isEmpty then Hot
598-
else eval(rhs, ref, target.owner.asClass, cacheResult = true)
603+
eval(rhs, ref, target.owner.asClass, cacheResult = true)
599604
else if target.exists then
600605
val obj = ref.objekt
601606
if obj.hasField(target) then
@@ -610,8 +615,7 @@ object Semantic:
610615
Hot
611616
else if target.hasSource then
612617
val rhs = target.defTree.asInstanceOf[ValOrDefDef].getRhs
613-
if rhs.isEmpty then Hot
614-
else eval(rhs, ref, target.owner.asClass, cacheResult = true)
618+
eval(rhs, ref, target.owner.asClass, cacheResult = true)
615619
else
616620
val error = CallUnknown(field)(trace)
617621
reporter.report(error)
@@ -735,8 +739,7 @@ object Semantic:
735739
reporter.reportAll(tryReporter.errors)
736740
extendTrace(ddef) {
737741
val rhs = ddef.getRhs
738-
if rhs.isEmpty then Hot
739-
else eval(rhs, ref, cls, cacheResult = true)
742+
eval(rhs, ref, cls, cacheResult = true)
740743
}
741744
else if ref.canIgnoreMethodCall(target) then
742745
Hot
@@ -822,8 +825,7 @@ object Semantic:
822825
else
823826
extendTrace(ddef) {
824827
val rhs = ddef.getRhs
825-
if rhs.isEmpty then Hot
826-
else eval(rhs, ref, cls, cacheResult = true)
828+
eval(rhs, ref, cls, cacheResult = true)
827829
}
828830
else if ref.canIgnoreMethodCall(ctor) then
829831
Hot
@@ -936,8 +938,7 @@ object Semantic:
936938

937939
case ref: Ref =>
938940
val rhs = vdef.getRhs
939-
if rhs.isEmpty then Hot
940-
else eval(rhs, ref, enclosingClass, cacheResult = sym.is(Flags.Lazy))
941+
eval(rhs, ref, enclosingClass, cacheResult = sym.is(Flags.Lazy))
941942
case _ =>
942943
report.warning("[Internal error] unexpected this value when accessing local variable, sym = " + sym.show + ", thisValue = " + thisValue2.show + Trace.show, Trace.position)
943944
Hot
@@ -1144,7 +1145,7 @@ object Semantic:
11441145
*
11451146
* The class to be checked must be an instantiable concrete class.
11461147
*/
1147-
private def checkClass(classSym: ClassSymbol)(using Cache.Data, Context): Unit =
1148+
private def checkClass(classSym: ClassSymbol)(using Cache.Data, Context, TreeCache.CacheData): Unit =
11481149
val thisRef = ThisRef(classSym)
11491150
val tpl = classSym.defTree.asInstanceOf[TypeDef].rhs.asInstanceOf[Template]
11501151

@@ -1179,6 +1180,7 @@ object Semantic:
11791180
*/
11801181
def checkClasses(classes: List[ClassSymbol])(using Context): Unit =
11811182
given Cache.Data()
1183+
given TreeCache.CacheData()
11821184
for classSym <- classes if isConcreteClass(classSym) && !classSym.isStaticObject do
11831185
checkClass(classSym)
11841186

@@ -1410,8 +1412,7 @@ object Semantic:
14101412
case vdef : ValDef =>
14111413
// local val definition
14121414
val rhs = vdef.getRhs
1413-
if rhs.isEmpty then Hot
1414-
else eval(rhs, thisV, klass)
1415+
eval(rhs, thisV, klass)
14151416

14161417

14171418
case ddef : DefDef =>
@@ -1631,7 +1632,7 @@ object Semantic:
16311632
// class body
16321633
if thisV.isThisRef || !thisV.asInstanceOf[Warm].isPopulatingParams then tpl.body.foreach {
16331634
case vdef : ValDef if !vdef.symbol.is(Flags.Lazy) && !vdef.getRhs.isEmpty =>
1634-
val res = eval(vdef.rhs, thisV, klass)
1635+
val res = eval(vdef.getRhs, thisV, klass)
16351636
// TODO: Improve promotion to avoid handling enum initialization specially
16361637
//
16371638
// The failing case is tests/init/pos/i12544.scala due to promotion failure.

0 commit comments

Comments
 (0)