-
Notifications
You must be signed in to change notification settings - Fork 136
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
ECJ fails: Problem detected during type inference: Unknown error at invocation of getReadOnly(P) #2413
Comments
For the record, this code compiles without errors WritableProperty.getReadOnly(property); When I click P readOnly = WritableProperty.getReadOnly(property); Really strange... |
Which Eclipse /Javac version was used? |
@hohwille please provide a single file snippet that reproduces the error - without dependencies to anything then jdk. |
Wow, this was more tricky than expected and it seems only to happen in a rather advanced scenario but here is my so far minimal code to reproduce the problem without any imports all in a single java file:
And with javac it is working:
Java version:
Eclipse version:
I also setup a different Java version:
|
The link gives me |
It was a link to a nightly build. Just take latest build you can find at https://download.eclipse.org/eclipse/downloads/index.html |
One more (inner) class eliminated and comments removed:
|
Wait for @stephan-herrmann analysis :) |
|
One more interface removed:
|
Further simplification:
|
Getting close to minimum (sorry for the spam, just trying to make analysis simpler for you):
|
No problem. Smaller is always better. |
Thanks, @hohwille for a tricky test case! The compiler actually "wants" to report:
At least we had the safety net to report something specific, rather than just exploding. The root cause is buried in type inference, of course: applicability inference yields a useful result, but then invocation type inference fails! For robustness we continue with the previous result but create a ProblemMethodBinding which later triggers the problem report, but that ProblemMethodBinding is a contradiction in itself:
From here I'll have to dive into invocation type inference to see why that fails, despite having a good solution already in hands. Wish me luck for a speedy fix to be smuggled into RC1 😄 |
Interesting history of ecj versions:
|
Things go wrong when we incorporate the following type bounds:
With type bounds 2 and 3 we apply the following from 18.3.1:
I haven't yet found anything suspicious in our implementation, but I have the feeling that JLS 18.3.1 perhaps wants to say "if neither Si nor Ti is a wildcard nor contains a wildcard as a type argument ..." rather than only requesting that only Si and Ti themselves should not be wildcards. |
That interpretation would let us accept the test program without causing any regressions in our test suite. |
Here's a variant that compiles fine:
I only changed this: - <P extends WritableProperty<?>>
+ <X,P extends WritableProperty<X>> So rather then saying that For a moment I was wondering if the spec intention is indeed to only accept the variant with
(replace (The program declares two type variables |
invocation of getReadOnly(P) tentative fix for eclipse-jdt#2413
Wow, I did not actually expect fast progress and more assumed to get feedback like "strange edge-case, simply workaround with cast" or so or maybe bug confirmation but no reaction for years (what usually happens in Oracle bug tracker with my javac & co. bugs). |
Thanks, @hohwille for your kind words 😄 Seems like I feel closely connected to this implementation of type inference after all these years. So not paying attention to an accurate bug report like this wouldn't make any sense, would it? :) |
Thanks, @hohwille for your kind words 😄 When the famous English mathematician G.H. Hardy was asked what his greatest contribution to mathematics was, Hardy unhesitatingly replied that it was the discovery of Ramanujan! (https://en.m.wikipedia.org/wiki/G._H._Hardy) I unhesitatingly take (grab!) some credit for your praise being the one who recruited and tasked @stephan-herrmann with the entire of the new type inference project in ECJ 😉 Not just type inference, we only half jokingly say if the defect report has something in between angle brackets, anything at all, assign it to Stephan! So he has been the defacto maintainer for much of generics in ECJ. (Now if only javac doesn't implement a bunch of extra constitutional behavior and both the reference compiler and JLS are perfectly aligned, it would make his and ECJ's job so much easier but that is a perfect world) Thank you @stephan-herrmann. |
Another fun fact: changing the order of super interfaces of
Look at "for some generic class or interface, G"! Types Interestingly, the concept of such a common supertype is quite common in JLS. So, are all applications of the concept underspecified? In our case the selection makes a difference, because the transition from Looking at the example one could guess that the implementation should pick the "nearest" supertype, but what is the nearest supertype of A and B in situations like the following?
|
invocation of getReadOnly(P) alternative fix for eclipse-jdt#2413
#2459 demonstrates how we can use the space left open by under-specification can be used to go from reject to accept: we simply prefer a more specific G over a less specific one. This alone doesn't make the selection deterministic in the general case, but it helps in this particular case IFF accept is the desired outcome. The same PR contains another example that essentially demonstrates that a method parameter with a type of the shape Ergo: it is clear that the current situation is inconsistent, but I can't read the mind of the specification to decide which direction is intended. I'll seek clarification. |
Indeed that sounds absolutely logical (cannot think of a case where this would lead to a wrong/worse result right now, but surely generic type system is complex enough that just with some brain processing you can ensure and think through everything). |
wrong, a value of type |
For a start see https://bugs.openjdk.org/browse/JDK-8319461?focusedId=14674674&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-14674674 😄 More to come on other channels. |
Let's see if we get an answer to https://mail.openjdk.org/pipermail/compiler-dev/2024-May/026577.html |
invocation of getReadOnly(P) fix for eclipse-jdt#2413 considering advice * by Maurizio Cimadamore: inspect all pairs of matching supertypes * by Dan Smith super type should use capture then upwards projection additionally + avoid incrementing captureId when capture is reused not created + account for nullability of downwardsProjection (ITB18) + follow-up cleaning of IC18.findRPrimeAndResultingBounds() + avoid some array<->list conversions
Two answers indeed, showing that none of my hypotheses was right :)
The latter applies two rules we didn't yet consider:
New fix pushed to #2488 |
…nvocation of getReadOnly(P) (#2488) fix for #2413 considering advice * by Maurizio Cimadamore: inspect all pairs of matching supertypes * by Dan Smith super type should use capture then upwards projection additionally + avoid incrementing captureId when capture is reused not created + account for nullability of downwardsProjection (ITB18) + follow-up cleaning of IC18.findRPrimeAndResultingBounds() + avoid some array<->list conversions
This resolved it. |
@stephan-herrmann thanks for fixing the bug. 👍 p.s.: Seems like in eclipse you are not using milestone feature of github. |
Some do. Back in the days of bugzilla I would never close a bug without setting the milestone, but somehow this never became a habit in github and so far nobody complained. I guess my original confusion is this: should the milestone be marked at the issue or at the PR or both? |
Yep, github could better treat them more as a single unit but it advanced scenarios there can be multiple PRs for the same issue and vice-versa. So for the answer is both. I have the rule to always assign the milestone to issue + PR before doing the merge. |
Lately I have been updating the milestone at both places. The dichotomy between PR and Issue also very often ends up bifurcation the discussions which is unfortunate. |
Lots of food for thought.
|
…nvocation of getReadOnly(P) (eclipse-jdt#2488) fix for eclipse-jdt#2413 considering advice * by Maurizio Cimadamore: inspect all pairs of matching supertypes * by Dan Smith super type should use capture then upwards projection additionally + avoid incrementing captureId when capture is reused not created + account for nullability of downwardsProjection (ITB18) + follow-up cleaning of IC18.findRPrimeAndResultingBounds() + avoid some array<->list conversions
…nvocation of getReadOnly(P) (eclipse-jdt#2488) fix for eclipse-jdt#2413 considering advice * by Maurizio Cimadamore: inspect all pairs of matching supertypes * by Dan Smith super type should use capture then upwards projection additionally + avoid incrementing captureId when capture is reused not created + account for nullability of downwardsProjection (ITB18) + follow-up cleaning of IC18.findRPrimeAndResultingBounds() + avoid some array<->list conversions
Sorry for delay but just wanted to finally confirm that in Eclipse 2024-09 the bug is fixed. |
Problem
I have a case with generics that is not compiled by EJC even though it seems perfectly valid and is accepted by javac as well.
It occurs in my OSS project exactly here:
https://github.com/m-m-m/entity/blob/f64a597454f32c7544826a2c4a171459f1937eb5/bean/src/test/java/io/github/mmm/entity/property/PropertyTest.java#L78
The inital generic
P
here is defined like this:https://github.com/m-m-m/entity/blob/f64a597454f32c7544826a2c4a171459f1937eb5/bean/src/test/java/io/github/mmm/entity/property/PropertyTest.java#L23
The signature of the static method is as following:
https://github.com/m-m-m/property/blob/b71d7b3c8a320beaa841e24ee29bd5039b647bda/core/src/main/java/io/github/mmm/property/WritableProperty.java#L51
And of course
Property
implementsWritableProperty
:https://github.com/m-m-m/property/blob/b71d7b3c8a320beaa841e24ee29bd5039b647bda/core/src/main/java/io/github/mmm/property/Property.java#L24
Expected result
Code compiles in Eclipse without errors.
Actual result
Compiler error:
If you need further details, I should test anything or I should isolate a minimum code-snippet to reproduce the error, do not hesitate to ask.
Side note
I seem to be one of the few Java developers on this planet that uses generics extensively and have also found many bugs in javac in this regard that Oracle seems to ignore. If you want to waste some time feel invited to have a look into my collection of such bugs:
m-m-m/util#166
I never implemented a compiler with type-inference but already implementing Java code to resolve
java.lang.reflect.Type
with optionally its surroundingType
toClass
(or Classes with upper and lower bound) was a nightmare that took me ~50x more time than planned. So you have my deepest respect implementing EJC.Workaround
Avoid type inference and cast manually:
However, the entire purpose of the static
getReadOnly
method is to avoid the ugly casts.Then I can also directly do this:
However, good about these kind of type-inference bugs is that there typically is a workaround so you are not blocked.
The text was updated successfully, but these errors were encountered: