-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Add "Xlint:implicit-no-annotation" #5915
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
Conversation
An implicit However, all |
Why exactly? I am working off of the comment in |
Because scala/scala3#1784 and scala/scala3#1785. Local implicit vals are only visible in the scope that follows them, so it is safe to let their type be inferred. Moreover, it is extremely annoying to write explicit types for local implicit vals. For example the Scala.js codebase is full of def someTransformation(tree: Tree): Tree = {
implicit val pos = tree.pos
...
} |
Makes sense to me. I'll try to make the change. |
36ea4c8
to
f092e93
Compare
Change made and tested. |
Thanks. I guess someone from the core team has to take over the technical review at this point. |
Here's the corresponding check in dotty: https://github.com/lampepfl/dotty/blob/d524e28ebc4a5dc445a11df2548d7c9ea586b745/compiler/src/dotty/tools/dotc/typer/Namer.scala#L1062 |
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.
It is also worth looking at the history of the corresponding rule in the wartremover
lint tool: https://github.com/wartremover/wartremover/commits/master/core/src/main/scala/wartremover/warts/ExplicitImplicitTypes.scala
It evolved to allow { impicit x => ... }
lambda params without an result type on the ValDef
representing the lamdba param x
; added an some sort of exception for implicit classes.
@@ -710,6 +710,9 @@ trait Namers extends MethodSynthesis { | |||
if (isScala) { | |||
if (nme.isSetterName(tree.name)) ValOrVarWithSetterSuffixError(tree) | |||
if (tree.mods.isPrivateLocal && tree.mods.isCaseAccessor) PrivateThisCaseClassParameterError(tree) | |||
if (tree.mods.isImplicit && !owner.isTerm && settings.warnImplicitNoAnnotation && tree.tpt.isEmpty) { | |||
reporter.warning(tree.pos, s"implicit value ${tree.name} has no type annotation") |
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.
Should be .name.decoded
to avoid displaying encoded names like '$colon$colon`.
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 term "type annotation" is widely understood but the spec talks about "result types" in this context (and about "type ascriptions" after expressions).
A precedent for wording of this sort of message is:
scala> def foo = { return 1; 1 }
<console>:11: error: method foo has return statement; needs result type
def foo = { return 1; 1 }
^
s/needs/should have a
and I think it fits 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 guess this is to avoid overloading the term "annotation" with @annotations
.)
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.
Not that further motivation is needed, but I expected it to warn about lacking an implicit not found annotation.
@@ -108,7 +108,7 @@ object ScalaOptionParser { | |||
"-g" -> List("line", "none", "notailcails", "source", "vars"), | |||
"-target" -> List("jvm-1.5", "jvm-1.6", "jvm-1.7", "jvm-1.8")) | |||
private def multiChoiceSettingNames = Map[String, List[String]]( | |||
"-Xlint" -> List("adapted-args", "nullary-unit", "inaccessible", "nullary-override", "infer-any", "missing-interpolator", "doc-detached", "private-shadow", "type-parameter-shadow", "poly-implicit-overload", "option-implicit", "delayedinit-select", "by-name-right-associative", "package-object-classes", "unsound-match", "stars-align"), | |||
"-Xlint" -> List("adapted-args", "nullary-unit", "inaccessible", "nullary-override", "infer-any", "missing-interpolator", "doc-detached", "private-shadow", "type-parameter-shadow", "poly-implicit-overload", "option-implicit", "delayedinit-select", "by-name-right-associative", "package-object-classes", "unsound-match", "stars-align", "no-implicit-annotation"), |
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.
Perhaps: implicit-result-type
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.
Without the rename, there is a typo here:
s/no-implicit-annotation/implicit-no-annotation
(The fact that you need to repeat yourself here is my fault, sorry...)
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'm curious; so my motivation was that it seems to be that all of these lint options are named for what they warn for. Nullary-unit, inaccessible, adapted args, these are all the "bad" that the lint option actually warns for itself. "implicit-result-type" seems inconsistent, because it would be named for the condition needed to not warn.
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 thought about it and I agree the rename is the most consistent option.
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.
This still looks unfixed?
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 can attest that naming these options is hard. I suspect no one will ever request -Xlint:poly-implicit-overload
. You warn for implicit-lacks-type
, or -Xlint:infer-X
, since the warning is triggered by inference. -Xlint:infer-implicit-type
.
When adding a new warning, it's a can be helpful to run it across a few projects and review the output. That often turns up false positives. You can also post a gist of the output to help us review. Here's how that looks for "re-starring" (using your modified compiler as the new reference compiler):
|
Does this also warn for implicit objects? Because they have the same problem. |
@edmundnoble, what's your plan regarding getting this across the finish line in time for 2.12.4? This would be a nice lint option and it looks like there isn't much more polish needed. To be included in 2.12.4, PRs must be mergeable (approved by reviewer) by Wed Sep 27. |
876630d
to
b688a4f
Compare
@retronym I've rebased, and added tests for the special cases you've mentioned: they didn't require any more changes to the warning check. I also changed "type annotation" to "result type" in the lint option and the warning itself. I'm considering maybe relaxing the |
We'll allow PRs currently scheduled for 2.12.4 to be merged until Friday, run benchmarks and community builds over the weekend and Monday, and cut the release on Tuesday. Any PRs that regress performance / break the community build will be reverted and rescheduled for 2.12.5. |
We ran out of time here for 2.12.4, but let's get this into a nightly as soon as all review comments are implemented. |
Ping! Is it a good time to merge this PR for 2.12.5 ? |
should I do a community build run so we can grep the log for the new warning and see what turns up? |
@edmundnoble as far as I can see there are still a few minor changes to be done:
@SethTisue the logic looks correct, so you can run it through the community build already now. |
I'm sorry this PR sat so long — we are really trying to do better on this in 2018 gah, and actually I can't run (not easily, anyway) the community build until this is rebased, the validate-publish-core job was deleted. @edmundnoble would you mind rebasing onto current 2.12.x...? |
Add local test Remove warning for local implicit vals More tests, inspired by WartRemover's Implicit object test
b688a4f
to
ce8ec43
Compare
@edmundnoble / @SethTisue I rebased and pushed -f to |
community build run queued: https://scala-ci.typesafe.com/view/scala-2.12.x/job/scala-2.12.x-integrate-community-build/2635/ |
That didn't go very far:
|
gah, that timed out. queued run 2645. builds from 2643 should still be cached, so when it comes time to grep the logs, we'll need to grep both of them together. |
(note that these runs don't explicitly enable the new flag everywhere, so we're only seeing the warnings for projects that have |
The build timed out; there's 125 lines with "has no type annotation" in the log, checking if those are all intended would give a good estimate. |
in run 2645 which is a continuation of 2643, there are a bunch of new compiler errors like:
|
this needs another rebase, now, in order to get better community build results |
Closing due to inactivity. Happy to accept a resubmission, though that should go to 2.13.x now. |
Maybe the community build should be peer-to-peer, with "volunteer" computers all over the world verifying every scala project for every commit. |
We promise we won't mine bitcoin in macros. |
This noble effort landed not as a lint but under |
Wondering if this needs a more self-explanatory name. Warns on implicits without type annotations.
Edit: Also please let me know if I am doing this in the wrong phase; I went as early as possible just because this info is available right away.