Skip to content

Commit f85d0c5

Browse files
committed
Add error-checking when fetching rhs of ValOrDefDefs.
1 parent 9066923 commit f85d0c5

File tree

1 file changed

+53
-16
lines changed

1 file changed

+53
-16
lines changed

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

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,23 @@ 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+
446463
// ----- Operations on domains -----------------------------
447464
extension (a: Value)
448465
def join(b: Value): Value =
@@ -576,8 +593,9 @@ object Semantic:
576593
case ref: Ref =>
577594
val target = if needResolve then resolve(ref.klass, field) else field
578595
if target.is(Flags.Lazy) then
579-
val rhs = target.defTree.asInstanceOf[ValDef].rhs
580-
eval(rhs, ref, target.owner.asClass, cacheResult = true)
596+
val rhs = target.defTree.asInstanceOf[ValDef].getRhs
597+
if rhs.isEmpty then Hot
598+
else eval(rhs, ref, target.owner.asClass, cacheResult = true)
581599
else if target.exists then
582600
val obj = ref.objekt
583601
if obj.hasField(target) then
@@ -591,8 +609,9 @@ object Semantic:
591609
// return `Hot` here, errors are reported in checking `ThisRef`
592610
Hot
593611
else if target.hasSource then
594-
val rhs = target.defTree.asInstanceOf[ValOrDefDef].rhs
595-
eval(rhs, ref, target.owner.asClass, cacheResult = true)
612+
val rhs = target.defTree.asInstanceOf[ValOrDefDef].getRhs
613+
if rhs.isEmpty then Hot
614+
else eval(rhs, ref, target.owner.asClass, cacheResult = true)
596615
else
597616
val error = CallUnknown(field)(trace)
598617
reporter.report(error)
@@ -715,7 +734,9 @@ object Semantic:
715734
else
716735
reporter.reportAll(tryReporter.errors)
717736
extendTrace(ddef) {
718-
eval(ddef.rhs, ref, cls, cacheResult = true)
737+
val rhs = ddef.getRhs
738+
if rhs.isEmpty then Hot
739+
else eval(rhs, ref, cls, cacheResult = true)
719740
}
720741
else if ref.canIgnoreMethodCall(target) then
721742
Hot
@@ -777,10 +798,13 @@ object Semantic:
777798
val tpl = cls.defTree.asInstanceOf[TypeDef].rhs.asInstanceOf[Template]
778799
extendTrace(cls.defTree) { init(tpl, ref, cls) }
779800
else
780-
val initCall = ddef.rhs match
781-
case Block(call :: _, _) => call
782-
case call => call
783-
extendTrace(ddef) { eval(initCall, ref, cls) }
801+
val rhs = ddef.getRhs
802+
if rhs.isEmpty then Hot
803+
else
804+
val initCall = rhs match
805+
case Block(call :: _, _) => call
806+
case call => call
807+
extendTrace(ddef) { eval(initCall, ref, cls) }
784808
end if
785809
else
786810
Hot
@@ -796,7 +820,11 @@ object Semantic:
796820
extendTrace(cls.defTree) { eval(tpl, ref, cls, cacheResult = true) }
797821
ref
798822
else
799-
extendTrace(ddef) { eval(ddef.rhs, ref, cls, cacheResult = true) }
823+
extendTrace(ddef) {
824+
val rhs = ddef.getRhs
825+
if rhs.isEmpty then Hot
826+
else eval(rhs, ref, cls, cacheResult = true)
827+
}
800828
else if ref.canIgnoreMethodCall(ctor) then
801829
Hot
802830
else
@@ -906,8 +934,10 @@ object Semantic:
906934

907935
case Cold => Cold
908936

909-
case ref: Ref => eval(vdef.rhs, ref, enclosingClass, cacheResult = sym.is(Flags.Lazy))
910-
937+
case ref: Ref =>
938+
val rhs = vdef.getRhs
939+
if rhs.isEmpty then Hot
940+
else eval(rhs, ref, enclosingClass, cacheResult = sym.is(Flags.Lazy))
911941
case _ =>
912942
report.warning("[Internal error] unexpected this value when accessing local variable, sym = " + sym.show + ", thisValue = " + thisValue2.show + Trace.show, Trace.position)
913943
Hot
@@ -1320,10 +1350,14 @@ object Semantic:
13201350
}
13211351

13221352
case closureDef(ddef) =>
1323-
Fun(ddef.rhs, thisV, klass)
1353+
val rhs = ddef.getRhs
1354+
if rhs.isEmpty then Hot
1355+
else Fun(rhs, thisV, klass)
13241356

13251357
case PolyFun(ddef) =>
1326-
Fun(ddef.rhs, thisV, klass)
1358+
val rhs = ddef.getRhs
1359+
if rhs.isEmpty then Hot
1360+
else Fun(rhs, thisV, klass)
13271361

13281362
case Block(stats, expr) =>
13291363
eval(stats, thisV, klass)
@@ -1375,7 +1409,10 @@ object Semantic:
13751409

13761410
case vdef : ValDef =>
13771411
// local val definition
1378-
eval(vdef.rhs, thisV, klass)
1412+
val rhs = vdef.getRhs
1413+
if rhs.isEmpty then Hot
1414+
else eval(rhs, thisV, klass)
1415+
13791416

13801417
case ddef : DefDef =>
13811418
// local method
@@ -1593,7 +1630,7 @@ object Semantic:
15931630

15941631
// class body
15951632
if thisV.isThisRef || !thisV.asInstanceOf[Warm].isPopulatingParams then tpl.body.foreach {
1596-
case vdef : ValDef if !vdef.symbol.is(Flags.Lazy) && !vdef.rhs.isEmpty =>
1633+
case vdef : ValDef if !vdef.symbol.is(Flags.Lazy) && !vdef.getRhs.isEmpty =>
15971634
val res = eval(vdef.rhs, thisV, klass)
15981635
// TODO: Improve promotion to avoid handling enum initialization specially
15991636
//

0 commit comments

Comments
 (0)