斯卡拉 3:"assertion failed: denotation class Int invalid in run 1."

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

我将 Scala 3 的编译器称为一个库,它在编译后为每个源提供 CompilationUnit。这有 tpdTree,听上去应该包含类型信息。

我正在尝试遍历树以获取任何类型符号:

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

树上行走的样子:

  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

我明白了

[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(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(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)

我做错了什么?

分辨率

在我的例子中,我的方法中有 (using ctx: Context),但显然它与 运行 上下文不匹配。如下显式传递它修复了它:

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

您需要 运行 在 run 值与创建定义时相同的上下文中进行查询(或者是较晚的 运行,但较早的 运行 无效)。

您看到的错误消息是您询问 运行 1 处符号的表示,这在概念上是在 运行 2 处创建之前的。

有关解释 run/phase 概念的视频,请参阅 https://www.youtube.com/watch?v=WxyyJyB_Ssc