-
Notifications
You must be signed in to change notification settings - Fork 3.1k
SI-10068 Only permit elidable methods #5539
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
Somebody clever:
Edit: it used to read |
4b5837c
to
557bf29
Compare
This PR is a regression, as the current compiler allows |
@Atry I think that was just a bug. The doc says:
It's kind of too bad Scala doesn't have the crazy Java ways to control where an annotation will stick. It worked by accident for vals by converting the RHS of the accessor method and replacing the field definition itself with an anomalous My first thought was to make it work for variables (see comment in test), but it doesn't work for constant value defs and lazy vals. It couldn't work for constants, though probably could be made to work for lazy vals. The shortcoming in this PR is that it still just silently ignores lazy vals.
|
I understand that the intent of this annotation is indeed to be for methods. I am not sure if there is code out there relying on this, but it's source-incompatible. Should this target 2.13 then? Regardless of that, I don't think |
@dragos I tried what I thought was the obvious spot in typer ( I don't have a strong opinion about 2.13, except that it's just a bug and not a de facto standard. I'd be generous if it weren't documented, or if the community build breaks. |
I don't feel strongly about 2.13, as you are right that it's forbidding a corner-case in a fairly esoteric option. However, I feel a bit stronger about where this check should be done. Besides the design intent of Typer and Uncurry, the latter is not run by the presentation compiler, so Ensime/Eclipse users won't be seeing these errors before building. If you are stuck, I'm sure there are people on scala-internals who could help. |
@dragos How about refchecks? There some annotation checks in Typers but it doesn't try too hard:
|
Much better! If you push a version in RefCheck I could have a look and see if it's easy to move one notch to the left, in Typer. :) |
Agree for preferring Typers (or RefChecks). You could put in 2.12 under |
0d9cc0d
to
737427d
Compare
|
737427d
to
194a3bf
Compare
Passes modulo mima. |
Looks good, thanks! The MiMa failure will go away after a rebase. @dragos, do you think the check should move to Typers? |
In refchecks, check that symbol with `@elidable` is a method. When eliding in uncurry, doublecheck. The check is enabled under `-Xsource:2.13`.
194a3bf
to
582c8a2
Compare
LGTM -- excellent! Also much pleased to see we're allocating fewer ScalaVersion objects :-) |
@@ -84,7 +84,10 @@ trait ScalaSettings extends AbsScalaSettings | |||
* though this helper. | |||
*/ | |||
def isScala211: Boolean = source.value >= ScalaVersion("2.11.0") | |||
def isScala212: Boolean = source.value >= ScalaVersion("2.12.0") | |||
private[this] val version212 = ScalaVersion("2.12.0") |
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.
Forgot ScalaVersion("2.11.0")
?
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 didn't want to push it.
@som-snytt I stumbled over this PR while enabling Also, the error is reported if the annotation is on an abstract method. This makes sense, as the annotation is not "inherited", we don't check if an overridden member has the annotation. I assume this is intentional? I'll update the error message, because it can be confusing:
|
Ah, the static type is relevant:
In 2.12, the above prints |
@lrytz I don't remember directly, but from the comments it looks like I had trouble detecting a lazy val when I was trying to support elidable lazy? I don't know what paranoia made me leave the later check. The message could have been augmented under debug, and then tests could document where the error was issued. I should have written more tests. Your clever example rings a bell, but it seems to me a reason not to allow it. Now we need a new lint rule to warn about overriding an elidable with a non-elidable. Which is the officially blessed lint project now? In the inverse case, the call to Not supporting vals is too bad. An elidable debug flag is an obvious use case. (It's a value with a useful natural default.) |
Lazy vals are caught by the first test, so probably it's just an oversight. Let's remove the report in UnCurry. About
Time, adoption, contributors will tell :-) You were the primary contributor to |
A use case would be a logger interface with implementations. My app code could then elide logger.log() entirely. Oh, in fact under separate compilation, my logger library needs the elidable abstract, since loggerImpl.log() won't be recompiled. Yeah, |
@lrytz thanks for the info. I'd wait for someone to ask for the feature, as there is no right path. I was only speaking hypothetically about a logger interface. My pet use case for elidable was for API prioritization, where methods marked "must have" would be enabled earlier in a development cycle. The elide level in the build would gradually fall until all features goals are met. That's also a hypothetical workflow. |
In uncurry, check that symbol with
@elidable
is a method.This fails to notice the annotation on lazy vals, which seems
to be a product of synthesis at namer/typer.
JIRA: https://issues.scala-lang.org/browse/SI-10068