Skip to content

Latest commit

 

History

History
46 lines (28 loc) · 2.4 KB

2.10.md

File metadata and controls

46 lines (28 loc) · 2.4 KB

Where has 2.10 support gone ?

This is a long answer, but an interesting one.

As part of the compilation step, scalac builds a data structure of the code, called an abstract syntax tree. This AST can then be modified by further compilation steps. For example, one of the steps is called uncurry and changes curried functions into the non-curried version that the JVM supports.

Each node in the scala AST has an associated position. This position can be in one of several states: no-position, meaning positional information was not available; offset which is the number of characters from the start of the file; range which gives you the start and end rather than just an offset. It is this range information that scoverage leverages to provide the pretty HTML output of code highlighted on a per-statement level. Without the range information it would not be able to highlight properly.

Range information is not enabled by default. To enable it one must use a compiler switch. Scoverage enables this switch as part of the build. Now, there is an interesting line of code in the compiler:

if (global.settings.Yrangepos && !global.reporter.hasErrors) global.validatePositions(unit.body)

This can be found in the typer phase of the compiler and it says: if range positions are enabled and there has been no errors reported, validate the tree.

What does validating the tree entail?

A number of checks, but the important one is checking that no range-enabled node is nested inside a non-range node. Why is this important? It wouldn't be, but for the kicker. Lots of macro code does not set range positions properly. The macro expanded code is inserted as part of this typer phase, and because of the lack of range information, the 2.10 validator fails.

When scoverage for Scala 2.10 was first released about a year ago, macros were fairly new, and almost no one used them. Over the past year macros have become commonplace, such as ScalaLogging, ReactiveMongo, Salat and other libraries using macros extensively.

This means scoverage falls foul of this issue. I don't know if one could call it a bug, since range positions are not activated by default, and if it is a bug, whether to blame macro writers, or the compiler, but the end result is that it doesn't work in 2.10 but does in 2.11[1]

Unfortunately this means 2.10 won't be supported any longer.

[1] https://issues.scala-lang.org/browse/SI-6743