@@ -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 =
@@ -576,7 +599,7 @@ object Semantic:
576
599
case ref : Ref =>
577
600
val target = if needResolve then resolve(ref.klass, field) else field
578
601
if target.is(Flags .Lazy ) then
579
- val rhs = target.defTree.asInstanceOf [ValDef ].rhs
602
+ val rhs = target.defTree.asInstanceOf [ValDef ].getRhs
580
603
eval(rhs, ref, target.owner.asClass, cacheResult = true )
581
604
else if target.exists then
582
605
val obj = ref.objekt
@@ -591,7 +614,7 @@ object Semantic:
591
614
// return `Hot` here, errors are reported in checking `ThisRef`
592
615
Hot
593
616
else if target.hasSource then
594
- val rhs = target.defTree.asInstanceOf [ValOrDefDef ].rhs
617
+ val rhs = target.defTree.asInstanceOf [ValOrDefDef ].getRhs
595
618
eval(rhs, ref, target.owner.asClass, cacheResult = true )
596
619
else
597
620
val error = CallUnknown (field)(trace)
@@ -715,7 +738,7 @@ object Semantic:
715
738
else
716
739
reporter.reportAll(tryReporter.errors)
717
740
extendTrace(ddef) {
718
- eval(ddef.rhs , ref, cls, cacheResult = true )
741
+ eval(ddef.getRhs , ref, cls, cacheResult = true )
719
742
}
720
743
else if ref.canIgnoreMethodCall(target) then
721
744
Hot
@@ -777,7 +800,7 @@ object Semantic:
777
800
val tpl = cls.defTree.asInstanceOf [TypeDef ].rhs.asInstanceOf [Template ]
778
801
extendTrace(cls.defTree) { init(tpl, ref, cls) }
779
802
else
780
- val initCall = ddef.rhs match
803
+ val initCall = ddef.getRhs match
781
804
case Block (call :: _, _) => call
782
805
case call => call
783
806
extendTrace(ddef) { eval(initCall, ref, cls) }
@@ -796,7 +819,7 @@ object Semantic:
796
819
extendTrace(cls.defTree) { eval(tpl, ref, cls, cacheResult = true ) }
797
820
ref
798
821
else
799
- extendTrace(ddef) { eval(ddef.rhs , ref, cls, cacheResult = true ) }
822
+ extendTrace(ddef) { eval(ddef.getRhs , ref, cls, cacheResult = true ) }
800
823
else if ref.canIgnoreMethodCall(ctor) then
801
824
Hot
802
825
else
@@ -906,8 +929,7 @@ object Semantic:
906
929
907
930
case Cold => Cold
908
931
909
- case ref : Ref => eval(vdef.rhs, ref, enclosingClass, cacheResult = sym.is(Flags .Lazy ))
910
-
932
+ case ref : Ref => eval(vdef.getRhs, ref, enclosingClass, cacheResult = sym.is(Flags .Lazy ))
911
933
case _ =>
912
934
report.warning(" [Internal error] unexpected this value when accessing local variable, sym = " + sym.show + " , thisValue = " + thisValue2.show + Trace .show, Trace .position)
913
935
Hot
@@ -1114,7 +1136,7 @@ object Semantic:
1114
1136
*
1115
1137
* The class to be checked must be an instantiable concrete class.
1116
1138
*/
1117
- private def checkClass (classSym : ClassSymbol )(using Cache .Data , Context ): Unit =
1139
+ private def checkClass (classSym : ClassSymbol )(using Cache .Data , Context , TreeCache . CacheData ): Unit =
1118
1140
val thisRef = ThisRef (classSym)
1119
1141
val tpl = classSym.defTree.asInstanceOf [TypeDef ].rhs.asInstanceOf [Template ]
1120
1142
@@ -1149,6 +1171,7 @@ object Semantic:
1149
1171
*/
1150
1172
def checkClasses (classes : List [ClassSymbol ])(using Context ): Unit =
1151
1173
given Cache .Data ()
1174
+ given TreeCache .CacheData ()
1152
1175
for classSym <- classes if isConcreteClass(classSym) && ! classSym.isStaticObject do
1153
1176
checkClass(classSym)
1154
1177
@@ -1320,10 +1343,10 @@ object Semantic:
1320
1343
}
1321
1344
1322
1345
case closureDef(ddef) =>
1323
- Fun (ddef.rhs , thisV, klass)
1346
+ Fun (ddef.getRhs , thisV, klass)
1324
1347
1325
1348
case PolyFun (ddef) =>
1326
- Fun (ddef.rhs , thisV, klass)
1349
+ Fun (ddef.getRhs , thisV, klass)
1327
1350
1328
1351
case Block (stats, expr) =>
1329
1352
eval(stats, thisV, klass)
@@ -1375,7 +1398,7 @@ object Semantic:
1375
1398
1376
1399
case vdef : ValDef =>
1377
1400
// local val definition
1378
- eval(vdef.rhs , thisV, klass)
1401
+ eval(vdef.getRhs , thisV, klass)
1379
1402
1380
1403
case ddef : DefDef =>
1381
1404
// local method
@@ -1593,8 +1616,8 @@ object Semantic:
1593
1616
1594
1617
// class body
1595
1618
if thisV.isThisRef || ! thisV.asInstanceOf [Warm ].isPopulatingParams then tpl.body.foreach {
1596
- case vdef : ValDef if ! vdef.symbol.is(Flags .Lazy ) && ! vdef.rhs .isEmpty =>
1597
- val res = eval(vdef.rhs , thisV, klass)
1619
+ case vdef : ValDef if ! vdef.symbol.is(Flags .Lazy ) && ! vdef.getRhs .isEmpty =>
1620
+ val res = eval(vdef.getRhs , thisV, klass)
1598
1621
// TODO: Improve promotion to avoid handling enum initialization specially
1599
1622
//
1600
1623
// The failing case is tests/init/pos/i12544.scala due to promotion failure.
0 commit comments