Description
This ticket is a follow up UX report/discussion following the changes in
#18634
and specifically, #19245 (this is the final PR, but the other PRs are relevant as well).
Compiler version
3.4.1-RC1 and above
Minimized code
def fn(n: Int): String =
val abc = 123
val dfe = 456
val xyz = 789
n.toString
Necessary compiler flags
scalac -Xfatal-warnings -Wunused:locals
Output Scala 3.3.3
-- Error: warnings.scala:2:6 ---------------------------------------------------
2 | val abc = 123
| ^^^
| unused local definition
-- Error: warnings.scala:3:6 ---------------------------------------------------
3 | val dfe = 456
| ^^^
| unused local definition
-- Error: warnings.scala:4:6 ---------------------------------------------------
4 | val xyz = 789
| ^^^
| unused local definition
3 errors found
Output Scala 3.4.1-RC2
-- Warning: warnings.scala:2:6 -------------------------------------------------
2 | val abc = 123
| ^^^
| unused local definition
-- Warning: warnings.scala:3:6 -------------------------------------------------
3 | val dfe = 456
| ^^^
| unused local definition
-- Warning: warnings.scala:4:6 -------------------------------------------------
4 | val xyz = 789
| ^^^
| unused local definition
No warnings can be incurred under -Werror (or -Xfatal-warnings)
3 warnings found
1 error found
Screenshots from Metals
- When using Bloop as the build server, Bloop manually upgrades warnings to fatal errors, in the presence of
-Xfatal-warnings
(but not-Werror
, separate issue):

- When using sbt as the build server, the warnings stay warnings, and the
No warnings can be incurred under -Werror (or -Xfatal-warnings)
error message is not reported anywhere. I believe this is due to this error message being issued without any source and position information.

- A control screenshot of using Scala 3.3.3, to establish a baseline expecation (captured using sbt as the build server, but Bloop is the same):

Discussion (originally posted in a Scala Center - VirtusLab - JetBrains collaboration channel, copied almost verbatim)
Let’s examine the -Xfatal-warnings/-Werror
change at a high level. We used to have compiler messages that could be treated as self-contained pieces of compilation information. This was achieved through the xsbti.Problem
interface, which contains all info that we might need to present a compiler issued message, be it in a build tool, or an editor.
With this latest change, a precedent has been set, each xsbti.Problem
is no longer self-contained. Instead, multiple xsbti.Problem
instances are part of a larger context, and need to be evaluated together, in order to decide whether an xsbti.Problem
needs to be modified after the fact.
And we already have inconsistencies because of this. Sbt (in the terminal) shows warnings and a single error at the end, just like the compiler issues the messages (i.e. does no further post processing). When using Metals with sbt, this is what the user will see as well (without the No warnings can be incurred
error message, whose absence makes things more confusing). From a user experience perspective, this is a regression. Scala 3.3 with -Xfatal-warnings
issues errors, and Scala 3.4 with the same -Xfatal-warnings
issues warnings, so the user will start seeing warning highlights in the editor, where they used to see error highlights prior to updating the Scala version. This will seem surprising to users, thinking that -Xfatal-warnings
is ignored.
The same is happening in IntelliJ IDEA as well, when using the compiler for error highlighting.
On the other hand, Bloop manually upgrades the warnings into errors. This has been confirmed by @tgodzik , and is an old feature of Bloop. I'm glad it exists and I'm using it as an illustration of UX inconsistencies in Scala tooling, in the hopes of converging on a consistent presentation to users.
What I would like to discuss is, given that this precedent has been set, how do we converge on a consistent UX across the tools and editors. And given that there are intentions to make Scala 3.4 even more resilient in the face of compilation errors, will this be the only case of “manually upgrading warnings to errors”, or will there be other, different combinations of messages where we need to do post processing on the compiler messages.
I’m tagging @szymon-rd and @nicolasstucki as the people who were directly involved in the implementation and review of this change, but anyone else is more than welcome to join the discussion.
Thanks in advance.