Community
Participate
Working Groups
I20050610-1200 Given, the following two classes which reside in the same package public class E<T, U extends Number> { boolean bool= false; char c= 0; byte b= 0; short s= 0; int i= 0; long l= 0; float f= 0; double d= 0; Boolean bool_class= null; Character c_class= null; Byte b_class= null; Short s_class= null; Integer i_class= null; Long l_class= null; Float f_class= null; Double d_class= null; Object object= null; Vector vector= null; Socket socket= null; Cloneable cloneable= null; Collection collection= null; Serializable serializable= null; Object[] objectArr= null; int[] int_arr= null; long[] long_arr= null; Vector[] vector_arr= null; Socket[] socket_arr= null; Collection[] collection_arr= null; Object[][] objectArrArr= null; Collection[][] collection_arrarr= null; Vector[][] vector_arrarr= null; Socket[][] socket_arrarr= null; Collection<String> collection_string= null; Collection<Object> collection_object= null; Collection<Number> collection_number= null; Collection<Integer> collection_integer= null; Collection<? extends Number> collection_upper_number= null; Collection<? super Number> collection_lower_number= null; Vector<Object> vector_object= null; Vector<Number> vector_number= null; Vector<Integer> vector_integer= null; Vector<? extends Number> vector_upper_number= null; Vector<? super Number> vector_lower_number= null; Vector<? extends Exception> vector_upper_exception= null; Vector<? super Exception> vector_lower_exception= null; T t= null; U u= null; Vector<T> vector_t= null; Vector<U> vector_u= null; Vector<? extends T> vector_upper_t= null; Vector<? extends U> vector_upper_u= null; Vector<? super T> vector_lower_t= null; Vector<? super U> vector_lower_u= null; } public class F<T, U extends Number> extends E<T, U> { void foo() { java.util.Vector<java.lang.Object> x= (java.util.Vector<java.lang.Object>) collection_upper_number; } } the statement in F#foo doesn't produce any compile error which is correct. However if I ask if the cast is legal using the method ITypeBinding#isCastCompatible the answer is false. The question we ask is: "TypeBinding for Vector<Object>".isCastCompatible("TypeBindig for Collection<? extends Number>" However casting Collection<? extends Number> to Vector<Object> is leagal. Side note: The isCastCompatible API looks strange to me regarding what this stands for and what the param stands for (it is the opposite way as I would naturally think ;-)). Our current usage however seems correct from the result point of view. Given we have two bindings b1 reprenting boolean b2 reprenting java.lang.Object then b1.isCastCompatible(b2) answers false since I can't cast an Obeject to a boolean b2.isCastCompatible(b1) answers true since I can cast a boolean to an Object under 5.0
Discussed it with Philippe, and the problem is that isCastCompatible now needs capture bindings for generics to answer correct questions. However the tests answer the question of bindings accessed from variable declaration fragments so they are not captured.
We have to check what to do here.
Need to be resolved within RC3 since UI ramifications.
Suspect it is a consequence of our tightening the casting rule which was too permissive. Need to see whether capturing expression type would improve behavior, but clearly the situation where the compiler would perform any cast test would involve captures in place of wildcards.
Tightening of casting rule corresponds to bug 98331
"TypeBinding for Vector<Object>".isCastCompatible("TypeBindig for Collection<? extends Number>" However casting Collection<? extends Number> to Vector<Object> is leagal. Actually, what the compiler sees is rather: Collection<capture-of ? extends Number> on the right hand side. I agree also that the API looks backward.
+1 for RC3 Dirk - pls cast your vote.
Just to clarify that I understand correcly what will be changed: - isCastCompatible will work for all sorts for type bindings again - the API will still stay backward. Are we considering deprecating the API and adding a new method which does the expected (e.g canCastTo). At least we should clarify the current API.
Appropriate action still need to be determined based on results of investigation. Ideally, it would look like what you described, but need to see what is possible there.
+1
Jim - can you please comment on the API looking backward ? If possible, we should fix it before too many start being impacted.
The spec does feel backwards. But I think it's pretty late to be changing the signature for 3.1. I suggest imrpoving the spec to call attention to it being backwards.
Ok. Suggest the following doc addition: * <p> * NOTE: The cast compatibility check performs backwards. * When testing whether type B can be cast to type A, one would use: * <code>A.isCastCompatible(B)</code> * </p>
I am enclined to force a free capture on DOM cast check so as to simulate the fact that in real code, it would occur. This is the least amount of change at this stage. Note that for the offending scenario, javac rejects the code; we do accept it. According to the JLS, only provably distinct types should be causing grief to cast compatibility, and this isn't the case here due to presence of wildcards (or type variables, when captured). This is another issue which is being debated with language spec.
Released fix for this situation. Locally it passes UI tests. Olivier - pls add a regression test for it.
Regression test added in ASTConverter15Test.test0191
Verified using N20050616-0010 + JDT/Core HEAD