| Summary: | [1.7][compiler] ecj behavior differs from javac | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | Srikanth Sankaran <srikanth_sankaran> | ||||||||||
| Component: | Core | Assignee: | Srikanth Sankaran <srikanth_sankaran> | ||||||||||
| Status: | VERIFIED FIXED | QA Contact: | |||||||||||
| Severity: | normal | ||||||||||||
| Priority: | P3 | CC: | markus.kell.r, Olivier_Thomann, satyam.kandula | ||||||||||
| Version: | 3.7 | Flags: | Olivier_Thomann:
review+
|
||||||||||
| Target Milestone: | 3.7.1 | ||||||||||||
| Hardware: | PC | ||||||||||||
| OS: | Windows XP | ||||||||||||
| Whiteboard: | |||||||||||||
| Bug Depends on: | |||||||||||||
| Bug Blocks: | 348956 | ||||||||||||
| Attachments: |
|
||||||||||||
I'll investigate this. Released disabled junit test org.eclipse.jdt.core.tests.compiler.regression.GenericsRegressionTest._test347426() into BETA_JAVA7 stream. I am investigating this. Reduced test case:
public class X<T> {
class A<T extends X<?>> {
B<? extends A<T>> x;
}
class B<T extends A<?>> {}
boolean b = ((A<?>)null).x == ((B<A<X<?>>>)null);
}
How can there be a A<?> that is also not "? extends X<?>" ?
It does look like a bug in eclipse. javac7 compiles this fine.
Note however that javac fails on this case while it compiles
the comment#0 case alright.
(In reply to comment #3) > Note however that javac fails on this case while it compiles > the comment#0 case alright. I meant to say javac5. javac6 fails on both. See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6450290 for some interesting discussion on a somewhat similar javac bug. Created attachment 196772 [details]
Early version of a fix.
Created attachment 196780 [details]
Improved patch - under test
Created attachment 196795 [details]
Proposed patch - under test.
Closer to final version - under test.
The latest patch fails to handle this variation which is
compiled alright by javac7:
public class X<T> {
class A<T extends X<? extends String>> {
B<? extends A<T>> x;
}
class B<T extends A<?>> {}
boolean b = ((A<? extends X<?>>)null).x == ((B<A<X<? extends String>>>)null);
}
Created attachment 196817 [details] Final patch Augmented to handle the scenario in comment# 9 Released in BETA_JAVA7 branch. Olivier, please take a look and let me know if some cases are still broken - TIA. Basically, given class A<T extends B<?>>, A<?> cannot be the universe of all possible parameterizations, but only that subset that conforms to ? extends B<?> and the compiler was not making allowance for this constraint during type equivalence checks. Looks good to me. Verified using Eclipse Java 7 Support(Beta) feature patch v20110623-0900. |
The following code used to compile with javac 5, stopped compiling with javac6 and started compiling again with javac7. Eclipse HEAD and BETA_JAVA7 refuse to compile it: public class X { class A<T extends B<?>> { } class B<T extends A<?>> { D<? extends B<T>> x; } class D<T extends B<?>> {} <E extends B<?>> X(E x, D<B<A<?>>> d) { if (x.x == d) { return; } } } This behavior difference needs to be understood. If I change the line with the if to if (x.x == 1) javac7 spits out this message: X.java:10: error: incomparable types: X.D<CAP#1> and int if (x.x == 1) { ^ where CAP#1,CAP#2 are fresh type-variables: CAP#1 extends X.B<CAP#2> from capture of ? extends X.B<CAP#2> CAP#2 extends X.A<?> from capture of ? 1 error which offers some clue as to what javac thinks the type x.x should be. Eclipse thinks the type of x.x. is X.D<capture#2-of ? extends X.B<capture#1-of ?>> Notice the fact that the type A is missing in eclipse assessment of the type.