Bug 159214 - [1.5] [compiler] Eclipse compiler wildcard bug
Summary: [1.5] [compiler] Eclipse compiler wildcard bug
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.3.2   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-09-28 19:45 EDT by Milan Stanojevic CLA
Modified: 2008-01-24 06:15 EST (History)
2 users (show)

See Also:
philippe_mulet: pmc_approved+


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Milan Stanojevic CLA 2006-09-28 19:45:12 EDT
Eclipse compiles the following code with no errors reported:
class A<T extends Number, S extends T> {
        A<? extends Long,? extends S> a;
}
This code shouldn't compile. 
Capture conversion of A<? extends Long, ? extends S> is
A<X,Y> where X has upper bound Long & Number, and Y has upper bound S & X. 
Now, X and Y should be subtypes of the bounds defined in A. 
X is subtype of Number, but Y is not subtype of X. Even in the first place S & X is not formed correctly since S and X are not in subtype relation.
To make things more clear we can see possible actual values for all type variables or wildcards.
T = Number, S = Number, ? extends Long = Long, ? extends S = Integer.
But Integer is not subtype of Long, so the A<? extends Long,? extends S> is not valid. 

It seems that capture conversion is not implemented correctly.
Comment 1 Olivier Thomann CLA 2006-09-28 19:54:55 EDT
javac 1.5.0_08 and 6.0b99 also accept this code.
Comment 2 Milan Stanojevic CLA 2006-09-28 20:00:38 EDT
(In reply to comment #1)
> javac 1.5.0_08 and 6.0b99 also accept this code.
> 

Yes, I checked that and I believe it's a bug there as well. 
Comment 3 Milan Stanojevic CLA 2006-09-28 21:14:35 EDT
On the same note:
Eclipse doesn't allow this:
class B<T extends Number> {
    B<? extends Object> b;
}
but javac does.

It seems to me that it should be allowed. 
Comment 4 Milan Stanojevic CLA 2006-09-28 22:13:33 EDT
Sorry for flooding but I think this example better illustrates that something is wrong.

class A<T extends Number, S extends T> {
  T t;
  S s;
  void test(A<? extends Long, ? extends S> a) {
    this.t = this.s; //fine
    a.t = a.s;       //eclipse compiler reports error
  }
}

Eclipse compiler doesn't allow second assignment. Clearly if a has a well formed type (as compiler suggests), the assignment should be allowed. 
Comment 5 Philipe Mulet CLA 2006-09-29 04:33:59 EDT
For original issue, the spec is usually considering that some constructs are tolerated at compile-time, since there is no way to construct the offending type. Certain cast checks are based on this assumption.
Will investigate still.
Comment 6 Milan Stanojevic CLA 2006-09-29 15:43:46 EDT
You might be right that the type should be allowed. Wildcards should be viewed as imposing additional constraints on type parameters. And reading the JLS capture conversion and intersection type specs, it seems that the type is ok. Having said that, the offending assignment from my last example should then definitely be allowed. 
Comment 7 Milan Stanojevic CLA 2006-10-05 16:36:24 EDT
After discussing this with people that know type systems (i.e. my advisor) I can see that this is not a bug. It is really hard to get this from JLS alone I guess. My mistake, sorry for trouble. 
Comment 8 Olivier Thomann CLA 2006-10-06 12:51:16 EDT
Added regression test in org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest#test1043/1044/1045
Comment 9 Milan Stanojevic CLA 2006-10-06 13:07:04 EDT
(In reply to comment #8)
> Added regression test in
> org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest#test1043/1044/1045
> 

test1044 should be rechecked. I believe that's a bug actually. javac does allow that declaration. 
A<? extends Object> in that case would be capture converted to A<X> where X is a new type variable with bound Object & Number, which is a proper intersection type. Object & Number is subtype of Number, so original bounds are also satisfied. I don't see the reason why A<? extends Object> would be disallowed.
Comment 10 Philipe Mulet CLA 2007-09-13 15:36:17 EDT
When tuning compiler for bug 202404, I realized your claim on the capture was valid. Reopening.

Re: comment 9
> A<? extends Object> in that case would be capture converted to A<X> where X is
> a new type variable with bound Object & Number, which is a proper intersection
> type. Object & Number is subtype of Number, so original bounds are also
> satisfied. I don't see the reason why A<? extends Object> would be disallowed.

I think the capture in this case shouldn't yield Object&Number, but simply Number, but this doesn't change the fact your last example should be accepted.
Comment 11 Philipe Mulet CLA 2007-09-13 18:25:49 EDT
Patch is combined with patch for bug 202404.
Released for 3.4M2

Fixed
Comment 12 David Audel CLA 2007-09-18 06:28:24 EDT
Verified for 3.4M2 using build I20070918-0010
Comment 13 Philipe Mulet CLA 2007-10-10 04:25:05 EDT
backporting to 3.3.2
Comment 14 Philipe Mulet CLA 2007-10-10 04:25:35 EDT
Released for 3.3.2
Fixed
Comment 15 Maxime Daniel CLA 2007-10-29 12:51:10 EDT
Only adding Verified for 3.4M2 to the status whiteboard, since I believe this
got lost.
Comment 16 Jerome Lanneluc CLA 2007-11-22 10:28:16 EST
The compiler semantics near capture conversion need to be tuned to match the
spec. Without these changes, we see quite many corner cases failing to compile
properly or being rejected incorrectly, and numerous customers starting to
notice it.
Comment 17 Philipe Mulet CLA 2007-11-23 09:20:55 EST
+1 for 3.3.2
Comment 18 Frederic Fusier CLA 2008-01-24 06:15:17 EST
Verified for 3.3.2 using build M20080123-0800.