Community
Participate
Working Groups
RC3 candidate The following code complains incorrectly about a duplicate bound T : public class X { <T extends Runnable, U extends Runnable & T> T foo() { return null; } }
The bound check diagnosis is incorrectly erasing supertypes, and thus thinks a type variable bound (T) means Runnable, and incorrectly thinks it is a duplicate. The type variable hierarchy computation should mimic the normal superinterfaces connection (for types) and also notice situations like: public class X { <T extends Runnable, U extends Runnable & T> T foo1() { return null; } <T extends Y<Object>, U extends Z & T> T foo2() { return null; } <T extends Y<Object>, U extends T & Z> T foo3() { return null; } <T extends Y<Object>, U extends W & Z> T foo4() { return null; } } interface Y<T> {} interface Z extends Y<String> {} interface W extends Y<Object> {} foo1 --> wrong as T doesn't act as an interface in formal bound foo2 --> OK (but javac rejects it incorrectly) foo3 --> incompatible supertype (RC3 doesn't notice) foo4 --> incompatible supertype (RC3 doesn't notice)
Fix has 2 parts: 1. stop tagging as interface a type variable with interface first formal bound. 2. reuse check from standard superinterfaces computation which detects collisions and duplicates correctly. Also get rid of unnecessary problem reporting code, since it reuses problem reporting from normal hierarchy computation. ---------- 1. ERROR in X.java (at line 2) <T extends Runnable, U extends Runnable & T> T foo1() { return null; } ^ The type T is not an interface; it cannot be specified as a bounded parameter ---------- 2. ERROR in X.java (at line 3) <T extends Y<Object>, U extends Z & T> T foo2() { return null; } ^ The type T is not an interface; it cannot be specified as a bounded parameter ---------- 3. ERROR in X.java (at line 5) <T extends Y<Object>, U extends W & Z> T foo4() { return null; } ^ The interface Y cannot be implemented more than once with different arguments: Y<String> and Y<Object> ----------
Added GenericTypeTest#test768, updated test429 to reflect error message improvements.
Created attachment 23614 [details] Patch for JDTCore
Created attachment 23615 [details] Patch for compiler tests
At this stage of the game, API changes are forbidden. So IProblem should remain untouched (with unused constant for obsoleted problem). This constant is unused by Eclipse SDK (only user would be quickfix anyway), but stil...
Fix looks good, but this case is unlikely to appear in many cases. I would postpone until 3.1.1
Fixed in 3.1 maintenance branch
Verified in 3.2 M1 with build I20050808-2000. Note that we now have a behavior comparable to javac's for foo2 - the type parameter is not accepted in place of an interface, even though it extends an interface.
Verified using M20050923-1430 for 3.1.1
(In reply to comment #10) > Verified using M20050923-1430 for 3.1.1 > Note that we now have a behavior comparable to javac's for foo2 - the type > parameter is not accepted in place of an interface, even though it extends > an interface. Hello. I stumbled over this while researching a problem of my own (with javac). I am currently under the impression that these incantations are not legal: a. <T extends Runnable, U extends Runnable & T>... b. <T extends Y<Object>, U extends Z & T>... The language spec (section 4.4) states that the only legal place for a type variable to appear in a bound is in the first position -- as in: <T extends Runnable, U extends T & Runnable>. Perhaps you have other knowledge though. I have not reached a conclusion on my difficulty. Good luck. Ciao, Steven Coco.
Forgive my clutter. I seem to have figured it out: If the type variable is specified, then this can be the only bound. The additional bounds are not allowed in this case. The language spec is worded too technically at this point. Have you got it worked out? If you'd like other references, in Gilad Bracha's generics tutorial, we see the use of <T extends Object & Comparable<? super T>> but not one with a type variable and additional bounds: http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf And this reference contains a reference to this point as well: http://pag.csail.mit.edu/~adonovan/hacks/generic-java/ Thanks... Steev Coco.
Pls see bug 106466, this is a slightly different issue.