Home > database >  Scala 3: "assertion failed: denotation class Int invalid in run 1."
Scala 3: "assertion failed: denotation class Int invalid in run 1."

Time:03-22

I am calling Scala 3's compiler as a library, which gives you CompilationUnit per source after compilation. This has tpdTree, which by the sound of it should contain type information.

I'm trying to walk the tree to get any type symbol as:

 atPhase(Phases.typerPhase.next) {
   // traverse unit.tpdTree...
 }

Where tree walking looks like:

  class ValExtractor(tpes: Set[String]) extends tpd.TreeTraverser:
    def isAcceptableType(tpe: Types.Type)(using ctx: Context): Boolean =
      tpe.baseClasses.exists { sym =>
        tpes.contains(sym.fullName.toString)
      }
    override def traverse(tree: tpd.Tree)(using ctx: Context): Unit =
      tree match
        case tpd.ValDef(name, tpt, _) if isAcceptableType(tpt.tpe) =>
          println("do something")
        case t: tpd.Template   => this((), t.body)
        case t: tpd.PackageDef => this((), t.stats)
        case t: tpd.TypeDef    => this((), t.rhs)
        case _                 => ()
  end ValExtractor

I get

[info]   assertion failed: denotation class Int invalid in run 1. ValidFor: Period(1..55, run = 2)
[info]     scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
[info]     dotty.tools.dotc.core.Denotations$SingleDenotation.updateValidity(Denotations.scala:719)
[info]     dotty.tools.dotc.core.Denotations$SingleDenotation.bringForward(Denotations.scala:744)
[info]     dotty.tools.dotc.core.Denotations$SingleDenotation.toNewRun$1(Denotations.scala:803)
[info]     dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:877)
[info]     dotty.tools.dotc.core.Symbols$Symbol.recomputeDenot(Symbols.scala:122)
[info]     dotty.tools.dotc.core.Symbols$Symbol.computeDenot(Symbols.scala:116)
[info]     dotty.tools.dotc.core.Symbols$Symbol.denot(Symbols.scala:109)
[info]     dotty.tools.dotc.core.Symbols$.toDenot(Symbols.scala:502)
[info]     dotty.tools.dotc.core.Denotations$SingleDenotation.updateValidity(Denotations.scala:718)
[info]     dotty.tools.dotc.core.Denotations$SingleDenotation.bringForward(Denotations.scala:744)
[info]     dotty.tools.dotc.core.Denotations$SingleDenotation.toNewRun$1(Denotations.scala:803)
[info]     dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:877)
[info]     dotty.tools.dotc.core.Types$NamedType.computeDenot(Types.scala:2253)
[info]     dotty.tools.dotc.core.Types$NamedType.denot(Types.scala:2213)
[info]     dotty.tools.dotc.core.Types$NamedType.info(Types.scala:2201)
[info]     dotty.tools.dotc.core.Types$TypeRef.underlying(Types.scala:2693)
[info]     dotty.tools.dotc.core.Types$Type.baseClasses(Types.scala:600)

What am I doing wrong?

Resolution

In my case I had (using ctx: Context) in my method, but apparently that did not match the run context. Passing it explicitly as follows fixed it:

atPhase(Phases.typerPhase.next) {
  (new ValExtractor(valTypes.toSet)).getVals(unit.tpdTree)
}(using run.runContext)

CodePudding user response:

You need to run the query in a context where the run value is the same as when the definitions were created (or is a later run, but an earlier run is not valid).

The error message you are seeing is that you ask about a denotation of a symbol at run 1, which is conceptually before it was created at run 2.

See https://www.youtube.com/watch?v=WxyyJyB_Ssc for a video where the run/phase concept is explained.

  • Related