Bug 99510 - isCastCompatible seems to need capture bindings now to answer correct results
Summary: isCastCompatible seems to need capture bindings now to answer correct results
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.1 RC3   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-06-11 07:26 EDT by Dirk Baeumer CLA
Modified: 2005-06-16 14:21 EDT (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dirk Baeumer CLA 2005-06-11 07:26:42 EDT
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
Comment 1 Dirk Baeumer CLA 2005-06-11 07:50:08 EDT
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.
Comment 2 Dirk Baeumer CLA 2005-06-11 07:51:30 EDT
We have to check what to do here.
Comment 3 Philipe Mulet CLA 2005-06-11 15:03:55 EDT
Need to be resolved within RC3 since UI ramifications.
Comment 4 Philipe Mulet CLA 2005-06-11 15:05:43 EDT
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.
Comment 5 Philipe Mulet CLA 2005-06-11 15:07:15 EDT
Tightening of casting rule corresponds to bug 98331
Comment 6 Philipe Mulet CLA 2005-06-12 04:01:24 EDT
"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.
Comment 7 Philipe Mulet CLA 2005-06-13 06:36:46 EDT
+1 for RC3

Dirk - pls cast your vote.
Comment 8 Dirk Baeumer CLA 2005-06-13 06:45:20 EDT
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.
Comment 9 Philipe Mulet CLA 2005-06-13 09:30:41 EDT
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.
Comment 10 Dirk Baeumer CLA 2005-06-13 18:09:43 EDT
+1
Comment 11 Philipe Mulet CLA 2005-06-14 04:54:42 EDT
Jim - can you please comment on the API looking backward ? If possible, we
should fix it before too many start being impacted.
Comment 12 Jim des Rivieres CLA 2005-06-14 08:46:12 EDT
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.
Comment 13 Philipe Mulet CLA 2005-06-14 10:27:54 EDT
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>
Comment 14 Philipe Mulet CLA 2005-06-14 10:44:10 EDT
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.
Comment 15 Philipe Mulet CLA 2005-06-14 12:14:13 EDT
Released fix for this situation.
Locally it passes UI tests. 

Olivier - pls add a regression test for it.
Comment 16 Olivier Thomann CLA 2005-06-14 13:02:55 EDT
Regression test added in ASTConverter15Test.test0191
Comment 17 Olivier Thomann CLA 2005-06-16 14:21:43 EDT
Verified using N20050616-0010 + JDT/Core HEAD