| Summary: | [1.8][compiler] Type mismatch: cannot convert from Class.OtherClass<Enum<Enum<K>>> to Class.OtherClass<K> | ||||||
|---|---|---|---|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | Gerard Paligot <gerard.paligot> | ||||
| Component: | Core | Assignee: | JDT-Core-Inbox <jdt-core-inbox> | ||||
| Status: | CLOSED WONTFIX | QA Contact: | |||||
| Severity: | normal | ||||||
| Priority: | P4 | CC: | eamonn, jarthana, leventov, stephan.herrmann | ||||
| Version: | 4.4.2 | ||||||
| Target Milestone: | --- | ||||||
| Hardware: | PC | ||||||
| OS: | Mac OS X | ||||||
| Whiteboard: | stalebug | ||||||
| Attachments: |
|
||||||
Thanks for the report. I don't think we need the test infrastructure, as we already have our own, but we might need the full Java file "Tacos.java". Could you please attach that? TIA. Created attachment 254110 [details]
Tacos.java file
Thanks, I can reproduce that
- javac accepts the program at 1.7 and 1.8
- ecj at 1.7 accepts the program
- ecj at 1.8 rejects the program
The problem should, however, be avoided in the source example: usage of raw types has been deprecated right when the concept was first introduced for Java 5. Raw-types don't harmonize well with type inference, and javac is known to use compatibility rules in this area, which violate JLS.
The following variant resolves the issue:
//--
private static <K extends Enum<K>> ATacos<K> make(Map<K, ?> map) {
return copyOfEnumMap((EnumMap<K,?>) map);
}
//--
Two changes made:
- added type arguments to EnumMap
- added a required type bound to <K> declaration of make
The second change is necessary to make a value of type EnumMap<K,?> a valied argument for copyOfEnumMap().
For me personally, trying to align ecj behavior with javac regarding how raw types are handled in type inference has very low priority.
Yes, it works with this change but, for me, there are two problems: 1. The Java in the sample is valid. So, it's maybe weird that JDT can't compile valid Java source code. 2. My sample come from another project than mine. I'm working on the open source project Spoon which analyses and transforms java source code. To do this, it uses JDT and I tried to compile Guava. So, for now, JDT can't compile Guava (I'll try to propose your fix in Guava). (In reply to Gerard Paligot from comment #4) > 1. The Java in the sample is valid. Let's not jump to conclusions, simply because some compilers happen to accept that code. javac is known to have a severe bug in handling raw types during type inference. Validity is defined by JLS not javac. (In reply to Gerard Paligot from comment #4) > (I'll try to propose your fix in Guava). I appreciate. In fact your mentioning of Guava seems to explain why I had a déjà-vu reading this report (though I couldn't find a duplicate in bugzilla). (In reply to Stephan Herrmann from comment #6) > (In reply to Gerard Paligot from comment #4) > > (I'll try to propose your fix in Guava). > > I appreciate. > > In fact your mentioning of Guava seems to explain why I had a déjà-vu > reading this report (though I couldn't find a duplicate in bugzilla). https://bugs.eclipse.org/bugs/show_bug.cgi?id=468119 Guava uses intentionally this practice of Java so I'm not able to applied your solution. I created an issue on Guava bugtracker here: https://github.com/google/guava/issues/2082 Well, Guava fixed my issue (https://github.com/google/guava/issues/2082#issuecomment-112835637) about the bug reported here, with this fix: https://github.com/google/guava/commit/f7048f587ea9e1cf3c6575e5918ef74eeb37b7c4. JDT is happy with it so, for me, this issue is okay. I let you the responsibility to close this issue or not (Maybe you would like handle this error if another project used this practice of Java 8). Unfortunately, I have a new bug but this isn't the subject of this one. I'll create a new issue. (In reply to Gerard Paligot from comment #9) > Well, Guava fixed my issue > (https://github.com/google/guava/issues/2082#issuecomment-112835637) about > the bug reported here, with this fix: > https://github.com/google/guava/commit/ > f7048f587ea9e1cf3c6575e5918ef74eeb37b7c4. > > JDT is happy with it so, for me, this issue is okay. Thanks, this is great news! > I let you the > responsibility to close this issue or not (Maybe you would like handle this > error if another project used this practice of Java 8). I'll leave this bug open, just at lower priority. Without thorough investigation I simply don't know which is the correct answer for this specific usage of raw types. This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug. If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie. |
I contribute on a open source project which used JDT 4.4.2 and I find a bug in JDT. We have this sample: ``` private static <K> ATacos<K> make(Map<K, ?> map) { return copyOfEnumMap((EnumMap) map); } private static <K extends Enum<K>> ATacos<K> copyOfEnumMap(EnumMap<K, ?> original) { return null; } ``` When I compile it with JDT, I got 1 error et 1 warning: ``` ---------- 1. ERROR in /Users/gerard/Documents/workspace/spoon/src/test/java/spoon/test/visibility/testclasses/Tacos.java (at line 22) return copyOfEnumMap((EnumMap) map); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Type mismatch: cannot convert from Tacos.ATacos<Enum<Enum<K>>> to Tacos.ATacos<K> ---------- 2. WARNING in /Users/gerard/Documents/workspace/spoon/src/test/java/spoon/test/visibility/testclasses/Tacos.java (at line 22) return copyOfEnumMap((EnumMap) map); ^^^^^^^ EnumMap is a raw type. References to generic type EnumMap<K,V> should be parameterized ---------- 2 problems (1 error, 1 warning) ``` If you would like, I have a test case: ``` @Test public void testCompileCaptureBinding18() throws Exception { final StandardEnvironment environment = new StandardEnvironment(); environment.setComplianceLevel(8); Factory factory = new FactoryImpl(new DefaultCoreFactory(), environment); JDTBasedSpoonCompiler compiler = new JDTBasedSpoonCompiler(factory); compiler.addInputSource(new File("./src/test/java/spoon/test/visibility/testclasses/Tacos.java")); compiler.compile(); } ``` This test case use a very light container class to build all arguments necessary for the compiler of JDT. You can find the implementation of JDTBasedSpoonCompiler here: https://github.com/INRIA/spoon/blob/master/src/main/java/spoon/support/compiler/jdt/JDTBasedSpoonCompiler.java#L582