Search code examples
scalasbtbreeze

sbt throws AssertionError at compilation with indecipherable error message


I've been getting these weird error messages when trying to recompile my sbt project, after adding some small changes to the code. Sometimes, depending on the edited code, the error disappears after cleaning the sbt project, but other times the error persists.

One example of how the error appears (but doesn't persist)

Adding this method to the Terrain class and compiling gives an error message that disappears after cleaning the project and recompiling:

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
}

Here are some snippets from the error message:

[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: 

and

[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$1(SpecializeTypes.scala:1573)

However, after following these steps, if you choose to remove that method from the Terrain class, it will again throw a similar error, but this time the source seems to have changed (to a different method, which had had no issue before and worked just fine). Again, by cleaning the build and recompiling, the error disappears.

Here is the change to the error message:

[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     }

What is weird is, sometimes after following these steps of adding some code, compiling and getting an error, cleaning the build and recompiling with no error and then removing said code and compiling to get a new error message, the apparent source of the new error might come from a completely different class, which was behaving just fine prior to that.

What is more, and this is actually my real issue, is that sometimes the change in code causes the error to persist despite cleaning the build.

It also doesn't help that the error message doesn't tell me much, and confusingly enough it seems to be pointing to the wrong source at times. I must confess however that I don't really understand how sbt works and I'm just using it to import some libraries, but I had no issues with it before.

EDIT: Apparently it's caused by the scala compiler, not sbt itself. Error message seems to be similar to this one: https://github.com/scala/bug/issues/9578

I've tested the code from that link and it does give the same type of error I was getting with my code (and the source presented in the error message is again irrelevant to the error). I am using breeze in my project, so that seems to be the source of the problem. I'll attempt to remove it from the project and see if the error still occurs.


Solution

  • I have managed to find the source of the problem, which as expected has nothing to do with sbt, but with Breeze. The problem is exactly the one in this open issue: https://github.com/scala/bug/issues/9578

    My workaround was to stop using DenseVector[Int] (right now I am using DenseVector[Float] but will probably switch to a different linear algebra library soon).