Bug 282152 - [1.5][compiler] Generics code rejected by Eclipse but accepted by javac
Summary: [1.5][compiler] Generics code rejected by Eclipse but accepted by javac
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.5   Edit
Hardware: PC Windows XP
: P3 normal with 1 vote (vote)
Target Milestone: 3.7 M3   Edit
Assignee: Srikanth Sankaran CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-07-01 09:19 EDT by Tomas Gradin CLA
Modified: 2010-10-26 06:08 EDT (History)
4 users (show)

See Also:


Attachments
tests & proposed fix (7.06 KB, patch)
2010-06-26 19:03 EDT, Stephan Herrmann CLA
no flags Details | Diff
Revised patch (7.17 KB, patch)
2010-10-21 00:41 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Final patch (8.36 KB, patch)
2010-10-25 04:51 EDT, Srikanth Sankaran CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Tomas Gradin CLA 2009-07-01 09:19:53 EDT
This code compiles with Sun's javac 1.6.0_13 but Eclipse rejects it:

interface Test<T extends Number> {
    public <T> Test<? extends Number> test(Test<? super T> t);
}

Eclipse gives the following error:

Bound mismatch: The type ? super T is not a valid substitute for the bounded parameter <T extends Number> of the type Test<T>
Comment 1 Stephan Herrmann CLA 2009-07-01 14:33:51 EDT
I'm not quite sure what this code fragment is intended to express since:

1. WARNING in Test.java (at line 2)
        public <T> Test<? extends Number> test(Test<? super T> t);
                ^
The type parameter T is hiding the type T

After making explicit the two different parameters, by changing
the interface declaration to "interface Test<U extends Number>"
the error changes accordingly to 

Bound mismatch: The type ? super T is not a valid substitute for the bounded parameter <U extends Number> of the type Test<U>

OK, the compiler wants to see evidence that "? super T" conforms to the
requirement of "U extends Number" - such evidence is not given.

If you next change the argument type from "Test<? super T>" to
"Test<T>" also javac complains: 

type parameter T is not within its bound

I have no idea why javac thinks that "? super T" is a more precise
type than "T", while the oposite is true.

So, without looking into the spec I don't see any reason why this
code should be accepted. Do you?

The code can be made to compile with both compilers by adding the
corresponding constraint to the declaration of T:

public <T extends Number> Test<? extends Number> test(Test<? super T> t);

Comment 2 Tomas Gradin CLA 2009-07-01 16:25:21 EDT
Yes, the T hides the other T, I should have changed that before posting it's not really the point here.

I agree, the compiler wants evidence that "? super T" works, which it doesn't get. So I have no idea either why javac accepts it.

But, it does, and if it does and Eclipse doesn't, either of them has a bug. I'm actually leaning towards the bug being in javac, but I thought I'd get an expert opinion first :)
Comment 3 Tomas Gradin CLA 2009-07-02 07:55:01 EDT
A (hopefully) clearer example:

interface Test<T extends Number> {
    public <U> void test(Test<? super U> t, U value);
}

How could there exist a Test<? super U> that is not of type Test<T extends Number>?

Maybe the bug is in Eclipse after all?
Comment 4 Maarten Coene CLA 2010-06-22 17:57:32 EDT
Any progress on this issue?
We are facing the same problem where IntelliJ IDEA can compile our code while Eclipse cannot, which makes it difficult for those who want to use Eclipse in our company.
Comment 5 Stephan Herrmann CLA 2010-06-26 19:03:25 EDT
Created attachment 172848 [details]
tests & proposed fix

At a closer look I actually agree that the example from comment 3 should
be accepted. I could not find a paragraph in the JLS that requires the lower
bound of a wildcard to be checked against the declared type parameters.
When capture conversion is involved it should not be a problem to have a
type with both an upper and a lower bound.
In such cases it should be a matter of the call site to provide a type 
that provably satisfies all constraints.

The tests include:
 - a slightly more elaborated version from comment 3 as a positive test
 - wrong usage of the doubly constrained argument
 - an attempt to define contradictory constraints
 - a compatible combination of constraints
 - attempt to pass a non-wildcard type parameter that is not compatible;
   since no capture conversion is involved the parameter must be provably
   substitutable, which it is not in this case.

The fix consists in simply skipping one check if a wildcard is lower-bounded
by a type variable that has no upper bound, because in this situation it is
still possible to provide a legal substitution for the wildcard.

If the wildcard has contradictory constraints it is a courtesy of the compiler
to report that no legal substitution exists for this wildcard.
Comment 6 Srikanth Sankaran CLA 2010-07-02 04:53:01 EDT
(In reply to comment #5)
> Created an attachment (id=172848) [details]
> tests & proposed fix

Thanks Stephen. I will follow up.
Comment 7 Srikanth Sankaran CLA 2010-07-21 01:35:49 EDT
(In reply to comment #6)
> (In reply to comment #5)
> > Created an attachment (id=172848) [details] [details]
> > tests & proposed fix
> 
> Thanks Stephen. I will follow up.

I haven't had time so far, will look at this in the 3.7 M2
time frame.
Comment 8 Olivier Thomann CLA 2010-09-13 11:40:04 EDT
Moving to M3 as Srikanth might be off till M2 is declared.
Comment 9 Srikanth Sankaran CLA 2010-10-21 00:41:31 EDT
Created attachment 181354 [details]
Revised patch

Same patch as before, synchronized with HEAD. Also
moved the tests to GenericsRegressionTest as GenericTypeTest
is getting too big and unwieldly.
Comment 10 Srikanth Sankaran CLA 2010-10-21 08:15:06 EDT
(In reply to comment #9)
> Created an attachment (id=181354) [details]
> Revised patch
> 
> Same patch as before, synchronized with HEAD. Also
> moved the tests to GenericsRegressionTest as GenericTypeTest
> is getting too big and unwieldly.

All tests pass. I'll experiment with a bit more before releasing
it for M3.
Comment 11 Srikanth Sankaran CLA 2010-10-25 04:51:50 EDT
Created attachment 181619 [details]
Final patch

Same patch as before, but with updated copyrights. 
Will release shortly. Thanks a lot Stephan.
Comment 12 Srikanth Sankaran CLA 2010-10-25 04:52:43 EDT
Released in HEAD for 3.7 M3
Comment 13 Jay Arthanareeswaran CLA 2010-10-26 06:08:21 EDT
Verified for 3.7M3 using build I20101025-0901.