Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 366131

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: CoreAssignee: Srikanth Sankaran <srikanth_sankaran>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: amj87.iitr, daniel_megert, jarthana
Version: 3.7.1Flags: daniel_megert: pmc_approved+
amj87.iitr: review+
Target Milestone: 3.6.2+J7   
Hardware: PC   
OS: Linux   
Whiteboard:
Attachments:
Description Flags
NumberRange.java: source file in which compile error occurs
none
Range.java: source file that compiles but is used by the source file that does not none

Description Ben Caradoc-Davies CLA 2011-12-08 22:41:05 EST
Build Identifier: 20110916-0149

The attached example source files demonstrate a new generics compile error found in Eclipse Indigo SR1. This has also been confirmed in Eclipse Juno M3. However, the examples compile in Helios SR2 and Indigo R, and also with javac from jdk1.6.0_29.x64 and jdk1.7.0_01.x64.

The error is:

"The method containsNC(Number&Comparable<? super Number&Comparable<? super N>>) in the type Range<Number&Comparable<? super Number&Comparable<? super N>>> is not applicable for the arguments (Comparable)"

Here is the GeoTools Jira issue:
GEOT-3971: NumberRange compile failure in Eclipse Indigo
https://jira.codehaus.org/browse/GEOT-3971

The original affected source file is here:
http://svn.osgeo.org/geotools/trunk/modules/library/metadata/src/main/java/org/geotools/util/NumberRange.java

If this isn't an argument against static typing, I don't know what is.  :-)

Reproducible: Always

Steps to Reproduce:
1. Open source files in Java editor in Eclipse SR1 or later.
Comment 1 Ben Caradoc-Davies CLA 2011-12-08 22:42:13 EST
Created attachment 208133 [details]
NumberRange.java: source file in which compile error occurs
Comment 2 Ben Caradoc-Davies CLA 2011-12-08 22:43:08 EST
Created attachment 208134 [details]
Range.java: source file that compiles but is used by the source file that does not
Comment 3 Ayushman Jain CLA 2011-12-09 00:13:43 EST
Reproduced.
Comment 4 Srikanth Sankaran CLA 2012-01-05 04:33:10 EST
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;
    }
}
Comment 5 Srikanth Sankaran CLA 2012-01-10 09:28:46 EST
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.
Comment 6 Srikanth Sankaran CLA 2012-01-10 10:02:40 EST
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.
Comment 7 Srikanth Sankaran CLA 2012-01-10 10:16:41 EST
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.
Comment 8 Ayushman Jain CLA 2012-01-11 01:19:13 EST
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
Comment 9 Dani Megert CLA 2012-01-11 04:19:12 EST
(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
Comment 11 Jay Arthanareeswaran CLA 2012-01-19 07:09:59 EST
Verified for 3.7.2 RC2 with build M20120118-0800
Comment 12 Jay Arthanareeswaran CLA 2012-01-23 10:14:30 EST
Verified for 3.8M5 using I20120122-2000