New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Integrate splain – implicit resolution chains and type diffs in error messages #7785
Conversation
You might consider grouping the compiler flags, |
@som-snytt could you elaborate how that would work? The only tool I'm seeing that allows grouping like this is |
That is, like The other possibility for avoiding a huge |
Note that you could also provide a man page for: |
ok, got it! |
any other suggestions? |
newSource1.scala:13: error: implicit error; | ||
!I e: II | ||
ImplicitChain.g invalid because | ||
!I impPar3: I1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find this message a bit hard to interpret. I have the impression that Dotty provides a more helpful error message (see an example here). Am I right, or are there limitations in what Dotty does that are addressed by splain?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the motivation for this notation is to be terse, concise and parsable in the face of implicit chains that are tens of levels deep. I haven't gotten any feedback on this by splain users so far, so I can't tell whether this is as useful to others as it is to me.
The test output with dummy names is certainly less readable than one where the involved names and types are recognizable, like circe.Decoder
and shapeless.Generic
, which is the intended use case.
One solution would certainly be to offer both verbose and terse messages, to be configured by the user.
Are you suggesting that Dotty's messages would make splain obsolete? Would that imply that it wouldn't be needed in current Scala?
I haven't looked at Dotty's implicit messages yet, does it display whole chains?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you suggesting that Dotty's messages would make splain obsolete?
Would that imply that it wouldn't be needed in current Scala?
This is not clear yet. In any case, it’s definitely useful to work on improving error messages!
I haven't looked at Dotty's implicit messages yet, does it display whole chains?
I have posted a comparison of messages produced by Scala and Dotty here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will have to investigate some test cases myself.
In any case, implicit conversions are not a feature that is handled by splain explicitly, just FYI.
My question now is: do you want to make this PR about how error messages should look? So far the mission was to make splain available as-is – if this should be different, we should make this an explicit statement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My question now is: do you want to make this PR about how error messages should look? So far the mission was to make splain available as-is – if this should be different, we should make this an explicit statement.
That’s a good point. I agree that working on how error messages should look could be done in another PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
marking as "resolved" because although further improvement would be welcome, it's not a blocker
Hi, what's the state of this PR? It's been some time since the last update :) |
I am waiting for activity! |
With the new github inbox for notifications, I'll never miss another review request. I'll get up to speed. First, I'll get up. |
@lrytz we're open to eventually merging this, right? I think you and I discussed it a few weeks ago but I admit that I forgot what we said. did we have any medium-sized-or-larger reservations about it? |
FWIW, I haven’t had a look at the PR implementation but I think the feature itself is extremely valuable. |
aaf22ed
to
6c24ea9
Compare
I also don't remember :-) My only reservation here is that the improvements live behind new compiler flags, and that the implementation is separate from the ordinary error messages and type printing. Can we integrate this deeper and make more people benefit from the helpful messages?
|
Even if we decide that this style of output should remain under a flag, perhaps one or more normal error messages could mention the flag, to improve discoverability. Regardless, I agree that deeper integration is better. Because passing flags is cumbersome; people tend to either turn a flag on all the time, or never. |
Frankly I'd rather have it soon as a flag than wait months and get new behavior as a default in a 2.13.x version :) |
@kubukoz that's understandable of course :-) However, features we add to the compiler are shipped to the entire Scala community, so changing things (even compiler flags or the style of error messages) comes with a cost, that's why things often move a bit slower. Also, from our perspective, it's a piece of code that we'll have to maintain for a long time, so it makes sense to integrate well into our codebase. For example, |
I would suggest starting out with the flag, since the plugin has so far only been used by people intentionally looking for the provided functionality, and some of the edge cases in, e.g. the found/req type diffs can be slightly buggy – not to the point of significant impediment, but it could probably need a bit of bug reporting. There's nothing keeping us from making it the default in the future, and it does feel like a lot of commitment to do it out of the gate. |
35% of the respondents in https://scalacenter.github.io/scala-developer-survey-2019/ say that "handling missing implicit errors" is a "main pain point in daily workflow". |
… messages This error formatting framework displays a tree of implicit parameters that correspond to the resolution chain between an error's call site and the offending implicit. Several additional improvements for error formatting are provided as well, like colored diffs of found/required error types, which are based on a set of pure data types extracted from the compiler internals, available to plugin developers through the AnalyzerPlugin API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(final review/merge by @lrytz?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM too!
The message formatting / wording can still be improved, that would be helpful. Basically what's discussed in these comments: https://github.com/scala/scala/pull/7785/files#diff-0d00a887e46a40735249285fb63ea04a8aa3de82943535fdfdbf86106cdcb88d
wooooo 🥳 🎉 |
WOOOOOOOOOOO! |
So does this close tek/splain#4? |
fuck yeah! |
There is some (trigger warning: somewhat grouchy) negative feedback at |
well, it isn't enabled by default, so not sure what else could be said 🙂 And the issue 38 talks about |
At this moment (Sept 2021), who is the maintainer/reviewer of this feature? There are a few hotfixes in splain 0.5.9 that wasn't included. Unfortunately the first patch to scala compiler takes a lot of copy and paste. IMHO, we can't afford to do this repeatedly for hotfixes. After consulting with @tek. I may have to rebase them on this repo |
any of us, all of us. PRs welcome |
@SethTisue thanks a lot. I've talked to @tek and discovered that many config options are also omitted: So I'll have to introduce them first. The following 2 PR should be ideally submitted in succession:
val keyAll = "all"
val keyImplicits = "implicits"
val keyFoundReq = "foundreq"
val keyInfix = "infix"
val keyBounds = "bounds"
val keyColor = "color"
val keyBreakInfix = "breakinfix"
val keyCompact = "compact"
val keyTree = "tree"
val keyBoundsImplicits = "boundsimplicits"
val keyTruncRefined = "truncrefined"
val keyRewrite = "rewrite"
val keyKeepModules = "keepmodules"
val analyzer =
new { val global = SplainPluginCompat.this.global } with Analyzer {
def featureImplicits = boolean(keyImplicits)
def featureFoundReq = boolean(keyFoundReq)
def featureInfix = boolean(keyInfix)
def featureBounds = boolean(keyBounds)
def featureColor = boolean(keyColor)
def featureBreakInfix = int(keyBreakInfix).filterNot(_ == 0)
def featureCompact = boolean(keyCompact)
def featureTree = boolean(keyTree)
def featureBoundsImplicits = boolean(keyBoundsImplicits)
def featureTruncRefined = int(keyTruncRefined).filterNot(_ == 0)
def featureRewrite = opt(keyRewrite, "")
def featureKeepModules = int(keyKeepModules)
} (feel free to suggest alternative names)
Wonder if I can catch the 2.13.7 release deadline? |
This integrates https://github.com/tek/splain into the compiler
-Vimplicits
makes the compiler print implicit resolution chains when no implicit value can be found-Vtype-diffs
turns type error messages (found: X, required: Y
) into colored diffs between the two typesI copied most of splain's code into the directory
src/compiler/scala/tools/nsc/typechecker/splain
and changed its integration to be less intrusive. There are now compiler options like-Ysplain
to control its behaviour. I kept the analyzer plugin method that allows consumers to override or amend output formatting, e.g. for providing more detailed messages about specific typeclasses with access to the typechecker and involved types.(previous PR at #5958).