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

Bug 321485

Summary: Eclipse gives compile error, while Sun JDK does not
Product: [Eclipse Project] JDT Reporter: Mekk Elek <mchallss>
Component: CoreAssignee: Stephan Herrmann <stephan.herrmann>
Status: VERIFIED DUPLICATE QA Contact:
Severity: major    
Priority: P3 CC: amj87.iitr, jarthana, manoj.palat, mchallss, stephan.herrmann
Version: 3.7   
Target Milestone: 4.7 M2   
Hardware: PC   
OS: Windows Vista   
Whiteboard:
Attachments:
Description Flags
LambdaJ changes that make the compile error disappear none

Description Mekk Elek CLA 2010-08-02 05:30:57 EDT
Build Identifier: 20100218-1602

I am using the LambdaJ (http://code.google.com/p/lambdaj/) library, which works and compiles fine using Netbeans, IntelliJ, those that uses the Sun JDK compiler. It does not compile in Eclipse with the internal Java compiler.

The lambdaj library can be fetched from:
http://lambdaj.googlecode.com/files/lambdaj-2.3-with-dependencies.jar


Reproducible: Always

Steps to Reproduce:
1.Download the lambdaj library from http://lambdaj.googlecode.com/files/lambdaj-2.3-with-dependencies.jar
2.Create a new Java project in Eclipse
3.Add the downloaded jar as an external library to the project
4.Create this class into the project that tries to use the LambdaJ library:

import static ch.lambdaj.Lambda.having;
import static ch.lambdaj.Lambda.on;
import static ch.lambdaj.collection.LambdaCollections.with;
import java.util.ArrayList;
import java.util.List;

public class Buggy {
  public static void main(String[] args) {
    ArrayList<Integer> mylist = new ArrayList<Integer>();
    List<Integer> containsList = with(mylist).clone(); // The keyword "with" will fail.
  }
}

5. Eclipse reports the following error:
"The method with(List<? extends Integer>) is ambiguous for the type Buggy"
6. If I prefix the "with" keyword with the package name like this:
List<Integer> containsList = ch.lambdaj.collection.LambdaCollections.with(mylist).clone();

The error will be:
"The method with(List<? extends Integer>) is ambiguous for the type LambdaCollections"
Comment 1 Ayushman Jain CLA 2010-08-02 06:24:59 EDT
Reproduced with  I20100608-0911. Srikanth, please investigate. Thanks!
Comment 2 Srikanth Sankaran CLA 2010-08-03 01:02:43 EDT
javac 5,6,7 compile clean. Eclipse behavior dates back at least to 3.3.2
probably earlier too. Under investigation.
Comment 3 Mekk Elek CLA 2010-08-07 13:33:00 EDT
Created attachment 176092 [details]
LambdaJ changes that make the compile error disappear

Hi,

the LambdaJ project fixed one thing in their libraries regarding this Eclipse bug. This attachement is the new version of their library (same as the official 2.3 with dependencies plus the fix).

The thread for the discussion of this Eclipse bug can be found here:
http://groups.google.com/group/lambdaj/browse_thread/thread/c19e626a059cd1d8/8284913c32872ee1#8284913c32872ee1

This is what they changed, quoted from the thread:
"Hi, 

thanks a lot for submitting the bug report. It seems an Eclipse issue 
indeed, but it seems I also made a small mistake on my side. 
In particular a colleague made me notice that I defined the with() 
methods accepting a Collection and a List in an inconsistent way since 
they are declared as it follows: 
with(Collection<T> collection) 
with(List<? extends T> list) 
I will fix this inconsistency with the next patch release, but now I 
am also wondering if it could be in some way related with the 
Eclipse's problem. 
Did somebody notice some similar problem? Could somebody quickly try 
to reproduce a similar situation in Eclipse? 
Should I report this detail on the Eclipse bug report? 

Bye, 
Mario"


This change in the LambdaJ library causes the reported Eclipse internal compiler error to disappear. So, the root cause for triggering the compile error can be narrowed down. Maybe the eclipse compiler is simply more rigid than the Sun JDK compiler, or maybe the original error is really a bug in the compiler, but at least now you can compare the two behaviors and decide if it is really a bug or rather a feature (i.e. to be more rigid than Sun compiler).

McHalls
Comment 4 Srikanth Sankaran CLA 2011-05-26 21:43:46 EDT
Small self contained examples that shows the problem:

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class X {

	public static <T> List<T> with(List<? extends T> p) { return null; } 
	public static <T> Collection<T> with(Collection<T> p) { return null; }

	public static void main(String[] args) {
            ArrayList<Integer> mylist = new ArrayList<Integer>();
            List<Integer> containsList = with(mylist);
        }
} 

I'll take a look and see what is going on here.
Comment 5 Srikanth Sankaran CLA 2011-05-26 21:53:40 EDT
Even shorter version:

import java.util.Collection;
import java.util.List;

public class X {
	public static <T> List<T> with(List<? extends T> p) { return null; } 
	public static <T> Collection<T> with(Collection<T> p) { return null; }
	static { with(null); }
}
Comment 6 Srikanth Sankaran CLA 2011-05-26 21:57:59 EDT
javac figures with(List<? extends T> p) to be more specific than
the other, while eclipse thinks neither is more specific.
Comment 7 Srikanth Sankaran CLA 2011-05-26 22:29:34 EDT
Released junit org.eclipse.jdt.core.tests.compiler.regression.AmbiguousMethodTest.test087()
into JAVA7 branch codifying current behavior. If eclipse behavior found to be 
incorrect, test will be changed suitably.
Comment 8 Srikanth Sankaran CLA 2011-05-27 01:18:50 EDT
This looks like a bug in javac - In both instances, both the compilers
infer T to be object given the call 

     with(null);

and now if I explicitly spell out the inferred arguments and create
a class as follows, javac starts complaining too.

import java.util.Collection;
import java.util.List;

public class X {
    public static List<Object> with(List<? extends Object> p) { return null; } 
    public static Collection<Object> with(Collection<Object> p) { return null; }
    static { 
    	with(null);
    }
}


I'll reread 15.12.2.5 one more time to see if I can glean some pointers
there.
Comment 9 Stephan Herrmann CLA 2013-12-08 18:34:16 EST
FYI: feeding the example from comment 4 into ecj as of sherrmann/NewTypeInference produces just one warning (unused local) and no error, whereas in 4.3.1 we still report an ambiguity error.
Comment 10 Stephan Herrmann CLA 2016-09-08 13:02:24 EDT
(In reply to Srikanth Sankaran from comment #8)
> This looks like a bug in javac - In both instances, both the compilers
> infer T to be object given the call 
> 
>      with(null);
> 
> and now if I explicitly spell out the inferred arguments and create
> a class as follows, javac starts complaining too.

I don't think instantiating type arguments before most specific method selection is a fair exercise, at least not in Java 8.

The conclusion here needs revisiting together with bug 111208.
Comment 11 Stephan Herrmann CLA 2016-09-08 16:26:38 EDT
After re-fixing bug 111208, AMT.test087() is a conformTest now.

No current plans to work on this for 1.7- though. Will give it a final thought in bug 501106.

*** This bug has been marked as a duplicate of bug 111208 ***
Comment 12 Jay Arthanareeswaran CLA 2016-09-14 01:34:16 EDT
Verified for 4.7 M2 with build I20160912-2000