Skip to content

Changes to -Xfatal-warnings lead to a UX regression in Scala tooling #20041

Closed as not planned
@vasilmkd

Description

@vasilmkd

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

  1. 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):
Screenshot 2024-03-28 at 10 02 37
  1. 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.
Screenshot 2024-03-28 at 10 05 33
  1. 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):
Screenshot 2024-03-28 at 10 07 41

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.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions