| Summary: | [1.5][compiler] New generics compile error in Indigo SR1 for code that compiles in earlier Eclipse and javac | ||||||||
|---|---|---|---|---|---|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | Ben Caradoc-Davies <Ben.Caradoc-Davies> | ||||||
| Component: | Core | Assignee: | Srikanth Sankaran <srikanth_sankaran> | ||||||
| Status: | RESOLVED FIXED | QA Contact: | |||||||
| Severity: | normal | ||||||||
| Priority: | P3 | CC: | amj87.iitr, daniel_megert, jarthana | ||||||
| Version: | 3.7.1 | Flags: | daniel_megert:
pmc_approved+
amj87.iitr: review+ |
||||||
| Target Milestone: | 3.6.2+J7 | ||||||||
| Hardware: | PC | ||||||||
| OS: | Linux | ||||||||
| Whiteboard: | |||||||||
| Attachments: |
|
||||||||
|
Description
Ben Caradoc-Davies
Created attachment 208133 [details]
NumberRange.java: source file in which compile error occurs
Created attachment 208134 [details]
Range.java: source file that compiles but is used by the source file that does not
Reproduced. Inlined test case:
class Range<T extends Comparable<? super T>> {
public boolean containsNC(T value) {
return false;
}
}
class NumberRange<T extends Number & Comparable<? super T>> extends Range<T> {
public boolean contains(Comparable<?> value) {
return castTo((Class) null).containsNC((Comparable) null);
}
public <N extends Number & Comparable<? super N>> NumberRange<N> castTo(Class<N> type) {
return null;
}
}
This is due to a latent old bug that has started manifesting itself after the fix for bug 341795. With the proper application of glb as per JLS3 15.12.2.8 we now infer the type variable N of the generic method castTo to be the intersection type described by the greater lower bounds of the published bounds as opposed to just the the first bound as we incorrectly used to prior to 3.7.1 This triggers a bug in the initialization method of ParamaterizedTypeBinding which fails to handle intersection types properly. As a result a generic type parameterized by an intersection type is confused with a parameterized type of the form X<?>. This in turns leads to our failing to recognize unchecked conversion in method argument passing which in turn leads to our failure in ... You get the idea. Fix is simple, a single line code change that fixes the obvious and clear oversight. Patch will follow shortly. Released fix and tests for 3.8 M5 via http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=3de7df3c8285dd5ccd5607560340925a143c9a94 Ayush, please review for 3.7.2 inclusion. Dani, Though the underlying bug is old, from a user p.o.v, this is a regression in 3.7.1. I would like to include this for 3.7.2 RC1 after code review. Fix is simple and obvious BTW. Note to reviewer: The Tagbit IsBoundParameterizedType is supposed to be set for all parameterized types NOT of the form X<?>. And so should be set for example for X<Number & Comparable>. Number & Comparable is an intersection type and the case for intersection types in the switch was failing to do this and has now been repaired. Looks good.
A few points that were raised, discussed and dismissed as false alarms:
1) There may be some more errors related to using a parameterized exception type in the throws or catch clause because org.eclipse.jdt.internal.compiler.lookup.TypeBinding.isBoundParameterizedType() now returns true for intersection type arguments. However, such an error can occur only if the exception type is itself generic, which is not allowed. This will also be reported an error, leading the compiler to bypass substituting type arguments at the usage of such an exception type in throws or catch clause. So the compiler will never encounter the intersection type case, and hence, no effect.
Test case used to validate the theory:
class NumberRange<T extends Number & Comparable<? super T>> extends Exception{
}
public class TypeArgs {
public <K extends Number & Comparable<? super K>> void foo () throws NumberRange<K>{
try {
} catch (NumberRange<K> n) {
}
}
}
2) There will be more unchecked warnings now because org.eclipse.jdt.internal.compiler.lookup.TypeBinding.needsUncheckedConversion(TypeBinding) now return true. However, these new warnings agree with javac and also with 3.7. So this is also good
(In reply to comment #6) > Released fix and tests for 3.8 M5 via > http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=3de7df3c8285dd5ccd5607560340925a143c9a94 > > Ayush, please review for 3.7.2 inclusion. > > Dani, Though the underlying bug is old, from a user p.o.v, > this is a regression in 3.7.1. I would like to include this > for 3.7.2 RC1 after code review. > > Fix is simple and obvious BTW. +1 for 3.7.2 and also 3.6.2+Java7 Released in 3.7 maintenance via http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?h=R3_7_maintenance&id=dc9727806573b42642839354adc5ac5c9252813e Released in 3.6.2+Java7 via http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?h=R3_6_maintenance_Java7&id=64eb28d2bc31dff6b049c5e79316bdee00301761 Verified for 3.7.2 RC2 with build M20120118-0800 Verified for 3.8M5 using I20120122-2000 |