Community
Participate
Working Groups
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.
javac 1.5.0_08 and 6.0b99 also accept this code.
(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.
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.
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.
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.
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.
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.
Added regression test in org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest#test1043/1044/1045
(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.
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.
Patch is combined with patch for bug 202404. Released for 3.4M2 Fixed
Verified for 3.4M2 using build I20070918-0010
backporting to 3.3.2
Released for 3.3.2 Fixed
Only adding Verified for 3.4M2 to the status whiteboard, since I believe this got lost.
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.
+1 for 3.3.2
Verified for 3.3.2 using build M20080123-0800.