Summary: | [1.5][compiler] regression - incorrect handling of generics | ||
---|---|---|---|
Product: | [Eclipse Project] JDT | Reporter: | Eric Goff <goffster> |
Component: | Core | Assignee: | Philipe Mulet <philippe_mulet> |
Status: | CLOSED FIXED | QA Contact: | |
Severity: | blocker | ||
Priority: | P3 | ||
Version: | 3.1 | ||
Target Milestone: | 3.1 RC2 | ||
Hardware: | PC | ||
OS: | Linux | ||
Whiteboard: |
Description
Eric Goff
2005-06-03 00:14:48 EDT
Reduced testcase: package foo; public class Test { public static void main(String[] args) { Controller<?> ctrl = null; foobar(ctrl.getView().getContent()); } static void foobar(Test t) { } } interface Controller<T extends View<?>> { public T getView() ; } interface View<U extends Test> { public U getContent(); } Reason for change is tightened capture conversion. When 'ctrl' gets capture conversion applied, what is the fresh type variable (say S) upper bound ? Is it: (1) strictly View<?> (2) or rather View<capture-of ?> ? (which I am guessing) If (1) is true, then the program should be rejected I think, as the type of ctrl.getView() would yield 'capture-of ?', then next call for #getContent() will issue '?' (from View<?>). Then this type hasn't been captured, and doesn't know enough to be a proper 'Test' as mandated by #foobar(...) invocation. If (2) is true, then it seems to indicate that capture conversion would have to recurse when computing the bounds of the fresh type variables. However, then I am wondering about infinite regressions when capturing some type Y<?> where class Y<T extends Y<?>> {}; if capturing is allocating a fresh variable each time it encounters Y<?>; could be closed by reusing same capture; but then it would change semantics and handle class Y<T extends Y<?>> {}; as if it had been defined: class Y<T extends Y<T>> {}; I can make this scenario work, by adding back type variable bounds in wildcard direct supertypes. But as demonstrated by following program, it reveals non substituted variables: public class X<E> { public static void main(String[] args) { Controller<?> ctrl = null; foobar(ctrl.getView().getContent()); } static void foobar(X<String> x) { } } interface Controller<T extends View<?>> { public T getView() ; } interface View<U extends X<U>> { public U getContent(); } javac: X.java:6: foobar(X<java.lang.String>) in X<E> cannot be applied to (X<U>) foobar(ctrl.getView().getContent()); ^ 1 error (U shouldn't appear outside its context !?) Tuned wildcard supertypes to meet old behavior and javac. May reconsider this behavior in the light of spec revision. Added GenericTypeTest#test726-728. Fixed Verified in N20050609-0010 + JDT/Core HEAD. Verified for 3.1 RC2 using build I20050610-0010 |