@@ -378,7 +378,7 @@ object Semantic:
378
378
// ----- Checker State -----------------------------------
379
379
380
380
/** 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
382
382
383
383
// ----- Error Handling -----------------------------------
384
384
@@ -443,6 +443,29 @@ object Semantic:
443
443
444
444
inline def reporter (using r : Reporter ): Reporter = r
445
445
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
+
446
469
// ----- Operations on domains -----------------------------
447
470
extension (a : Value )
448
471
def join (b : Value ): Value =
@@ -562,7 +585,7 @@ object Semantic:
562
585
case ref : Ref =>
563
586
val target = if needResolve then resolve(ref.klass, field) else field
564
587
if target.is(Flags .Lazy ) then
565
- val rhs = target.defTree.asInstanceOf [ValDef ].rhs
588
+ val rhs = target.defTree.asInstanceOf [ValDef ].getRhs
566
589
eval(rhs, ref, target.owner.asClass, cacheResult = true )
567
590
else if target.exists then
568
591
val obj = ref.objekt
@@ -577,7 +600,7 @@ object Semantic:
577
600
// return `Hot` here, errors are reported in checking `ThisRef`
578
601
Hot
579
602
else if target.hasSource then
580
- val rhs = target.defTree.asInstanceOf [ValOrDefDef ].rhs
603
+ val rhs = target.defTree.asInstanceOf [ValOrDefDef ].getRhs
581
604
eval(rhs, ref, target.owner.asClass, cacheResult = true )
582
605
else
583
606
val error = CallUnknown (field)(trace)
@@ -701,7 +724,7 @@ object Semantic:
701
724
else
702
725
reporter.reportAll(tryReporter.errors)
703
726
extendTrace(ddef) {
704
- eval(ddef.rhs , ref, cls, cacheResult = true )
727
+ eval(ddef.getRhs , ref, cls, cacheResult = true )
705
728
}
706
729
else if ref.canIgnoreMethodCall(target) then
707
730
Hot
@@ -768,7 +791,7 @@ object Semantic:
768
791
val tpl = cls.defTree.asInstanceOf [TypeDef ].rhs.asInstanceOf [Template ]
769
792
extendTrace(cls.defTree) { init(tpl, ref, cls) }
770
793
else
771
- val initCall = ddef.rhs match
794
+ val initCall = ddef.getRhs match
772
795
case Block (call :: _, _) => call
773
796
case call => call
774
797
extendTrace(ddef) { eval(initCall, ref, cls) }
@@ -787,7 +810,7 @@ object Semantic:
787
810
extendTrace(cls.defTree) { eval(tpl, ref, cls, cacheResult = true ) }
788
811
ref
789
812
else
790
- extendTrace(ddef) { eval(ddef.rhs , ref, cls, cacheResult = true ) }
813
+ extendTrace(ddef) { eval(ddef.getRhs , ref, cls, cacheResult = true ) }
791
814
else if ref.canIgnoreMethodCall(ctor) then
792
815
Hot
793
816
else
@@ -897,8 +920,7 @@ object Semantic:
897
920
898
921
case Cold => Cold
899
922
900
- case ref : Ref => eval(vdef.rhs, ref, enclosingClass, cacheResult = sym.is(Flags .Lazy ))
901
-
923
+ case ref : Ref => eval(vdef.getRhs, ref, enclosingClass, cacheResult = sym.is(Flags .Lazy ))
902
924
case _ =>
903
925
report.error(" [Internal error] unexpected this value when accessing local variable, sym = " + sym.show + " , thisValue = " + thisValue2.show + Trace .show, Trace .position)
904
926
Hot
@@ -1105,7 +1127,7 @@ object Semantic:
1105
1127
*
1106
1128
* The class to be checked must be an instantiable concrete class.
1107
1129
*/
1108
- private def checkClass (classSym : ClassSymbol )(using Cache .Data , Context ): Unit =
1130
+ private def checkClass (classSym : ClassSymbol )(using Cache .Data , Context , TreeCache . CacheData ): Unit =
1109
1131
val thisRef = ThisRef (classSym)
1110
1132
val tpl = classSym.defTree.asInstanceOf [TypeDef ].rhs.asInstanceOf [Template ]
1111
1133
@@ -1140,6 +1162,7 @@ object Semantic:
1140
1162
*/
1141
1163
def checkClasses (classes : List [ClassSymbol ])(using Context ): Unit =
1142
1164
given Cache .Data ()
1165
+ given TreeCache .CacheData ()
1143
1166
for classSym <- classes if isConcreteClass(classSym) do
1144
1167
checkClass(classSym)
1145
1168
@@ -1298,7 +1321,7 @@ object Semantic:
1298
1321
}
1299
1322
1300
1323
case closureDef(ddef) =>
1301
- Fun (ddef.rhs , thisV, klass)
1324
+ Fun (ddef.getRhs , thisV, klass)
1302
1325
1303
1326
case PolyFun (body) =>
1304
1327
Fun (body, thisV, klass)
@@ -1353,7 +1376,7 @@ object Semantic:
1353
1376
1354
1377
case vdef : ValDef =>
1355
1378
// local val definition
1356
- eval(vdef.rhs , thisV, klass)
1379
+ eval(vdef.getRhs , thisV, klass)
1357
1380
1358
1381
case ddef : DefDef =>
1359
1382
// local method
@@ -1571,8 +1594,8 @@ object Semantic:
1571
1594
1572
1595
// class body
1573
1596
if thisV.isThisRef || ! thisV.asInstanceOf [Warm ].isPopulatingParams then tpl.body.foreach {
1574
- case vdef : ValDef if ! vdef.symbol.is(Flags .Lazy ) && ! vdef.rhs .isEmpty =>
1575
- val res = eval(vdef.rhs , thisV, klass)
1597
+ case vdef : ValDef if ! vdef.symbol.is(Flags .Lazy ) && ! vdef.getRhs .isEmpty =>
1598
+ val res = eval(vdef.getRhs , thisV, klass)
1576
1599
// TODO: Improve promotion to avoid handling enum initialization specially
1577
1600
//
1578
1601
// The failing case is tests/init/pos/i12544.scala due to promotion failure.
0 commit comments