Does anyone else find Scala 3 error formatting horribly noisy and unhelpful?

There might also be a way to make the command line UX even better in VS Code thanks to “Quick Actions”:

2 Likes

Revisiting the thread because I’m tweaking the “stubs” view of unimplemented members.

-- Error: /home/amarki/projects/scala/test/files/neg/abstract-report.scala:1:6 -
1 |class Unimplemented extends scala.collection.IterableOps[String, List, List[String]]
  |      ^^^^^^^^^^^^^
  |class Unimplemented needs to be abstract, since:
  |it has 6 unimplemented members.
  |/** As seen from class Unimplemented, the missing signatures are as follows.
  | *  For convenience, these are usable as stub implementations.
  | */
  |  // Members declared in scala.collection.IterableOnce
  |  def iterator: Iterator[String] = ???
  |
  |  // Members declared in scala.collection.IterableOps
  |  protected def coll: List[String] = ???
  |  protected def fromSpecific
  |  (coll: IterableOnce[String @uncheckedVariance]): List[String] = ???
  |  def iterableFactory: scala.collection.IterableFactory[List] = ???
  |  protected def newSpecificBuilder:
  |  scala.collection.mutable.Builder[String @uncheckedVariance, List[String]] = ???
  |  def toIterable: Iterable[String] = ???
1 error found

in Scala 3 compared to Scala 2

/home/amarki/projects/scala/test/files/neg/abstract-report.scala:1: error: class Unimplemented needs to be abstract.
Missing implementations for 6 members.
  // Members declared in scala.collection.IterableOnce
  def iterator: Iterator[String] = ??? // implements `def iterator: Iterator[A]`

  // Members declared in scala.collection.IterableOps
  protected def coll: List[String] = ??? // implements `protected def coll: C`
  protected def fromSpecific(coll: scala.collection.IterableOnce[String]): List[String] = ??? // implements `protected def fromSpecific(coll: scala.collection.IterableOnce[A @scala.annotation.unchecked.uncheckedVariance]): C`
  def iterableFactory: scala.collection.IterableFactory[List] = ??? // implements `def iterableFactory: scala.collection.IterableFactory[CC]`
  protected def newSpecificBuilder: scala.collection.mutable.Builder[String,List[String]] = ??? // implements `protected def newSpecificBuilder: scala.collection.mutable.Builder[A @scala.annotation.unchecked.uncheckedVariance,C]`
  def toIterable: Iterable[String] = ??? // implements `def toIterable: Iterable[A]`

class Unimplemented extends scala.collection.IterableOps[String, List, List[String]]
      ^
1 error

The complaint about “needs to be abstract” is at this topic.

I observe there is no redundant [error] in this output from scala-cli, so I assume that is sbt.

In this output, the hyphens are for alignment with the gutter.

The “suggested edit” ought to be easy to copy/paste, so I wonder if such “quick fixes” should be rendered in the final summary, and without the gutter. I think there is a PR for missing member patches. It would be the responsibility of the tool to render (let’s say) multiline insertions after the errors.

I propose a verbose option for “beginner-friendly”, where -explain is reserved for the tedious explanation. Perhaps -Vmessages is on by default, and easy to turn off with -Vmessages:false.

A great job interview question would be, “Do you prefer -Vmessages? How about -explain? Do you do the crossword with a pen?”

I like the @lrytz suggestion: As a dev, I want to interact with source code, not build tool config. If I want more info about my class C, I’d rather annotate it with @explain, as a hint that I need more help with problems in that area of code.

Also as a dev, I’m accustomed to adding println debug to code that is executed in contexts I’m not interested in. I must scroll back to find my relevant output.

A local annotation could be used by many tools: my debugger could breakpoint only when dynamically in an @explain region, and my explain"this happened" would print only in an explaining context.

2 Likes

I think this might related, I am experimenting on making the explain a much more accessible feature within metals. We should be able to always show it to user on click.

Which then leads to a separate file:

This is very similar to what Rust does, though we register the file as markdown instead of showing raw diagnostic.

This should be available in 3.8.1 and 3.3.8. For older versions we should be able to link to error code descriptions that are being worked on in Document Scala compiler error codes by WojciechMazur · Pull Request #24734 · scala/scala3 · GitHub

It was suggested that maybe showing it in a separate file is not the best UX experience, but not sure if we can get it to be much better. This will also work for all VS Code based editors. For other editors we’ll most likely have a dedicated code action that creates the file in .metals directory.

Potentially we could replace the diagnostic being shown, but it might easily get out of sync and be more confusing than helpful.

If anyone has any opinions, let us know. I will try to get it out after the new year.

5 Likes