Description
The original issue is here: scoverage/sbt-scoverage#203
I investigated, how it works with different Scala versions (2.10.6, 2.11.8 and 2.12.0) on very simple trait:
package test
trait TraitWithFinalVal {
final val FOO = "Bar"
}
I don't feel qualified to fix this issue, this description is for @sksamuel (or anyone knowing scalac internals).
Scoverage during instrumentation replaces simple constant
"Bar"
with a block:
{
scoverage.Invoker.invoked(1, "path/to/scoverage-data");
"Bar"
}
The type of this block should be equal to the type of the last statement ("Bar"
).
It's set by this typer call:
val apply = invokeCall(id)
val block = Block(List(apply), tree)
localTyper.typed(atPos(tree.pos)(block)) // <------ here
What are the types of uninstrumented and instrumented val in different Scala versions:
Scala version | uninstrumented (simple value) type | instrumented (block) type | difference? | problem? |
---|---|---|---|---|
2.10.6 | String | String | no | no |
2.11.8 | String("Bar") | String | yes | no |
2.12.0 | String("Bar") | String | yes | YES! |
As you can see, after instrumentation the resulting block type is different from val type even with Scala 2.11, but it doesn't lead to compiler error. I found the exact git commit which changed things - it's scala/scala@50462a4
I'm not sure if typed
method returns wrong type, or Scoverage should not depend on it and set the type of the block to the type of the constant (something like setType(tree.tpe)
).