-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #2797: Don't lift Java annotation arguments out of call #2819
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
Thank you for minimizing @OlivierBlanvillain ! The scala/compiler-benchmark project compiles with this workaround and the unit tests pass. The annotations still seem to be emitted weirdly since I hit a new error when running the jmh benchmarks
I don't know if that error is related to this issue or not, the |
@olafurpg Last commit should moves the annotation from getter/setter methods to the actual field, let me know if that's enough to make JMH happy! |
I can confirm that the JMH benchmark runs from the latest commit! Thank you @OlivierBlanvillain |
Any chance to get this merged? It would help unblock scala/compiler-benchmark#31 |
It needs a review, @odersky could you have a look? |
@odersky could you please review it today so we can get it into next milestone? |
@smarter I am not sure how Scala annotations with default arguments are handled in the backend. Maybe @DarkDimius knows more? |
I tried a translation to Scala; seems to work. |
@@ -0,0 +1,7 @@ | |||
// Test is pending because we have no good way to test it. |
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 don't understand why this test is pending, since Fork is suffixed with 1 and Test with 2, they should be compiled as you want
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.
They are not. I get: "Not found: Fork" when I compile Test.
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've fixed the test. The issue was that the annotation needed to be called Fork_1
since the name of the file is Fork_1.java
. The javac error messages are eaten by our test suite, there's a WIP PR to fix that at #2811
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.
Ah, good to know.
This is nessary for interactiong with java libraries such as JMH. Matches scalac's behavior.
Lifting such arguments breaks the contract with the backend, which expects to see default getters inline, not lifted out.
- Java-defined annotation constructors need to have JavaDefined set. - Change the points where we suppress lifting. One case slipped through before. - Also: Add test.
Test is pending because we have no good way to test it. We need to: Compile Fork.java, and then compile Test.scala with Fork.class on the classpath.
Fork_1.java failed to compile before because the class name did not match the filename.
It might not crash in the backend, but the Scala test case still generates some weird code: @{
<accessor> val value$1: Int = Fork.$lessinit$greater$default$1
<accessor> val jvmArgs$1: Array{scala$Array$$T = String} =
Array.apply[String](["I\'m","hot" : String])(
scala.reflect.ClassTag.apply[String](classOf[class String])
)
new Fork(Test.this.value$1, Test.this.jvmArgs$1) It looks like scalac does something similar but with a warning: % scalac tests/pos/i2797a/Fork.scala tests/pos/i2797a/Test.scala
tests/pos/i2797a/Test.scala:4: warning: Usage of named or default arguments transformed this annotation
constructor call into a block. The corresponding AnnotationInfo
will contain references to local values and default getters instead
of the actual argument trees
@Fork(jvmArgs = Array("I'm", "hot"))
^ |
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 since this is an improvement on the current situation
While the test now succeeds under separate compilation, it fails join compilation (which happens to be tested by the legacy tests currently), you can reproduce that by running: dotc tests/pending/pos/i2797/Fork_1.java tests/pending/pos/i2797/Test_2.scala This fails with: -- Error: tests/pending/pos/i2797/Test_2.scala:4:0 ------------------------------------- 4 |@Fork_1(jvmArgs = Array("I'm", "hot")) |^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |missing argument for parameter value of constructor Fork_1: (value: |Int, jvmArgs: Array[String]): Fork_1 Because the JavaParsers output a constructor for Fork_1 without default values, to fix this we need JavaParsers to do something similar to ClassfileParser#addAnnotationConstructor
Had to disable i2797 again because of joint compilation failure, see last commit, I'll open an issue for that. |
In fact, we could put i2797 in pos-special and have legacyTests not try it. |
Looks like separate compilation is not used with |
Here is a minimized version, the reproduction requires loading the annotation from a class file:
2797.java:
2797.scala: