Community
Participate
Working Groups
Eclipse (build I20110514-0800) rejects the following valid code while javac7b138 compiles it fine. interface Super<P> {} class Y implements Super<Integer>{} interface X extends Super<Double>{} class S<L> extends Y {} interface T<L> extends X{} public class Test{ public static void main(String argv[]) { S s = null; // also if I use S<Byte> T t = null; // also if I use T<Byte> t = (T) s; } } This was also a bug in javac 5,6 which was fixed by http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6559182. Quoting the explanation from that bug - "In that example, T<L> has the following supertypes: *) T<L> *) X *) Super<Double> while S<L> has the following supertypes *) S<L> *) Y *) Super<Integer> In our example we have a cast from a type S (raw) to a type T (raw). Since the target type is an interface, the rule to be used for cast is the folowing (from JLS 5.5): "If [source] is a class type: [...] * If [target] is an interface type: o If [source] is not a final class (ยง8.1.1), then, if there exists a supertype X of [target], and a supertype Y of [source], such that both X and Y are provably distinct parameterized types, and that the erasures of X and Y are the same, a compile-time error occurs. Otherwise, the cast is always legal at compile time (because even if [source] does not implement [target], a subclass of S might)." At first it may seems that a compiler error should be raised since there are indeed two provably distinct supertypes of T<L> and S<L>, namely Super<Double> and Super<Integer>. But in the example the target type is a raw type so JLS 4.8 applies "The superclasses (respectively, superinterfaces) of a raw type are the erasures of the superclasses (superinterfaces) of any of its parameterized invocations." The supertypes of the target type T can be rewritten as follows: *) T *) X *) Super it can be seen how, after we pick the correct supertypes for the raw T, the conflict between Super<Integer> and Super<Double> simply disappear. So this code should indeed compile."
Note that as given in the above bug, the following should still fail interface Super<P> {} class Y implements Super<Integer>{} interface X extends Super<Double>{} class S extends Y {} interface T extends X{} public class Test{ public static void main(String argv[]) { S s = null; T t = null; t = (T) s; } }
I think this is fixed in the BETA_JAVA7 branch. We should double check that and simply backport the fix.
I would target 3.7.1 to match the Java 7 behavior when the Java 7 support is released.
(In reply to comment #2) > I think this is fixed in the BETA_JAVA7 branch. We should double check that and > simply backport the fix. Fix is already in HEAD, See bug 334493 *** This bug has been marked as a duplicate of bug 334493 ***
Verified.