sbt 在编译时抛出 AssertionError 并带有无法辨认的错误信息

sbt throws AssertionError at compilation with indecipherable error message

在对代码添加一些小的更改后,尝试重新编译我的 sbt 项目时,我收到了这些奇怪的错误消息。有时,根据编辑的代码,清理 sbt 项目后错误消失,但其他时候错误仍然存​​在。

错误出现的一个例子(但不会持续存在)

将此方法添加到 Terrain class 并编译给出了一条错误消息,该消息在清理项目并重新编译后消失:

def genChunkInputData(p: Vector3i): FloatBuffer = {
    val inputData = MemoryUtil.memAllocFloat(4 * (Chunk.SIZE+ 1) * (Chunk.SIZE+ 1) * (Chunk.SIZE+ 1))
    val r = (0 to Chunk.SIZE + 1)
    for (i <- r; j <- r; k <- r) {
        inputData.put(0.1F + 0.5F*min(i, Chunk.SIZE - i).toFloat/ Chunk.SIZE). //RED
                  put(0.1F + 0.5F*min(j, Chunk.SIZE - j).toFloat/ Chunk.SIZE). //GREEN
                  put(0.1F + 0.5F*min(k, Chunk.SIZE - k).toFloat/ Chunk.SIZE).//BLUE
                  put(isovalue((i + p(2)*Chunk.SIZE).toDouble, (j + p(1)*Chunk.SIZE).toDouble, (k + p(0)*Chunk.SIZE).toDouble)) //ISOVALUE
    }
    inputData.flip()
    inputData
}

以下是错误消息的一些片段:

[error] ## Exception when compiling 21 sources to D:\Computer science\Scala\Meandering Depths\target\scala-2.13\classes
    [error] java.lang.AssertionError: assertion failed:
    [error]   List(method apply$mcI$sp, method apply$mcI$sp)
    [error]      while compiling: D:\Computer science\Scala\Meandering Depths\src\main\scala\game\Terrain.scala
    [error]         during phase: globalPhase=specialize, enteringPhase=explicitouter
    [error]      library version: version 2.13.3
    [error]     compiler version: version 2.13.3
    [error]   reconstructed args: 

[error]
[error]   last tree to typer: Select(Ident(r), foreach$mVc$sp)

[error]        tree position: line 77 of D:\Computer science\Scala\Meandering Depths\src\main\scala\game\Terrain.scala
[error]             tree tpe: (f: Int => Unit): Unit
[error]               symbol: (final override) method foreach$mVc$sp in class Range
[error]    symbol definition: final override def foreach$mVc$sp(f: Int => Unit): Unit (a MethodSymbol)
[error]       symbol package: scala.collection.immutable
[error]        symbol owners: method foreach$mVc$sp -> class Range
[error]            call site: method $anonfun$genChunkInputData in package game
[error]
[error] == Source file context for tree position ==
[error]
[error]     74     def genChunkInputData(p: Vector3i): FloatBuffer = {
[error]     75         val inputData = MemoryUtil.memAllocFloat(4 * (Chunk.SIZE+ 1) * (Chunk.SIZE+ 1) * (Chunk.SIZE+ 1))
[error]     76         val r = (0 to Chunk.SIZE)
[error]     77         for (i <- r; j <- r; k <- r) {
[error]     78                     inputData.put(0.1F + 0.5F*min(i, Chunk.SIZE - i).toFloat/ Chunk.SIZE). //RED
[error]     79                               put(0.1F + 0.5F*min(j, Chunk.SIZE - j).toFloat/ Chunk.SIZE). //GREEN
[error]     80                               put(0.1F + 0.5F*min(k, Chunk.SIZE - k).toFloat/ Chunk.SIZE).//BLUE
[error] scala.reflect.internal.SymbolTable.throwAssertionError(SymbolTable.scala:170)
[error] scala.reflect.internal.Symbols$Symbol.suchThat(Symbols.scala:2024)[error] scala.tools.nsc.transform.SpecializeTypes$SpecializationTransformer.matchingSymbolInPrefix(SpecializeTypes.scala:1573)

然而,在完成这些步骤后,如果您选择从 Terrain class 中删除该方法,它会再次抛出类似的错误,但这次源似乎已经改变(到不同的方法,之前没有问题并且工作得很好)。同样,通过清理构建并重新编译,错误消失了。

这里是对错误消息的更改:

[error]   last tree to typer: Function(value $anonfun)
[error]        tree position: line 150 of D:\Computer science\Scala\Meandering Depths\src\main\scala\game\Terrain.scala
[error]             tree tpe: Int => Unit
[error]               symbol: value $anonfun
[error] == Source file context for tree position ==
[error]
[error]    147

[error]    148     private def isovalue(x: Double, y: Double, z: Double): Float = {
[error]    149         var res = -0.1F
[error]    150         for (i <- 0 until 4)
[error]    151             res += amp(i) * noise(i).noise3_XYBeforeZ(freq(i) * x, freqY(i) * y,freq(i) * z).toFloat
[error]    152         res
[error]    153     }

奇怪的是,有时在执行添加一些代码、编译并出现错误、清理构建并重新编译且没有错误,然后删除所述代码并编译以获取新错误消息的这些步骤之后,明显新错误的来源可能来自完全不同的 class,在此之前它表现得很好。

此外,这实际上是我真正的问题是,有时代码更改会导致错误仍然存​​在,尽管清理了构建。

错误消息并没有告诉我太多信息,这也无济于事,而且令人困惑的是,它似乎有时指向错误的来源。但是我必须承认,我并不真正理解 sbt 是如何工作的,我只是用它来导入一些库,但我之前没有遇到过问题。

编辑:显然它是由 scala 编译器引起的,而不是 sbt 本身。错误消息似乎与此类似:https://github.com/scala/bug/issues/9578

我已经测试了 link 中的代码,它确实给出了与我的代码相同类型的错误(并且错误消息中显示的源再次与错误无关)。我在我的项目中使用 breeze,所以这似乎是问题的根源。我将尝试将其从项目中删除并查看错误是否仍然存在。

我已经找到问题的根源,果然与sbt无关,而是与Breeze有关。问题正是这个公开问题中的问题:https://github.com/scala/bug/issues/9578

我的解决方法是停止使用 DenseVector[Int](现在我正在使用 DenseVector[Float],但可能很快会切换到不同的线性代数库)。