-
Enhancement
-
Resolution: Fixed
-
P3
-
7
-
None
-
unknown
-
generic
-
Verified
The original implementation of type-inference was very different w.r.t. to what is mandated by JLS3. In particular one of the features of jdk 5/6 javac that is not supported by the JLS is the ability of applying inference from argument types (15.12.2.7) several times (not just one as JLS mandate) until no further progress is made. This feature allows javac to infer more types than JLS does, e.g.
1) class MyMap implements Map<String, Integer> { ... }
<Z extends Map<X,Y>, X, Y> X getMap(Z z) { ... }
getMap(new MyMap());
This calls infers Z = MyMap and then, in a subsequent inference round, also X = String and Y = Integer are derived.
2) Another common situation where javac behaved differently w.r.t. the JLS3 is the following:
<X extends Y, Y> Y get(X x) { ... }
get("Hello!");
In this case, the first inference round infers X = String, but also, as a side effect sets a lower bound (String) on Y; this lower bound can be exploited in a subsequent inference round so that Y = lub(String) = String.
Bottom line: javac's type-inference used to be more powerful than JLS type-inference. In an attempt to make javac more compliant w.r.t. to JLS, a CCC request has been submitted 2 years ago and the jdk 7 compiler (and 6-open as well, as the fix got in before the 6-open branch) is now more JLS-compliant; which unfortunately means that javac now rejects a lot of code that used to compile without problems.
1) class MyMap implements Map<String, Integer> { ... }
<Z extends Map<X,Y>, X, Y> X getMap(Z z) { ... }
getMap(new MyMap());
This calls infers Z = MyMap and then, in a subsequent inference round, also X = String and Y = Integer are derived.
2) Another common situation where javac behaved differently w.r.t. the JLS3 is the following:
<X extends Y, Y> Y get(X x) { ... }
get("Hello!");
In this case, the first inference round infers X = String, but also, as a side effect sets a lower bound (String) on Y; this lower bound can be exploited in a subsequent inference round so that Y = lub(String) = String.
Bottom line: javac's type-inference used to be more powerful than JLS type-inference. In an attempt to make javac more compliant w.r.t. to JLS, a CCC request has been submitted 2 years ago and the jdk 7 compiler (and 6-open as well, as the fix got in before the 6-open branch) is now more JLS-compliant; which unfortunately means that javac now rejects a lot of code that used to compile without problems.
- relates to
-
JDK-6369608 inference: Inferred types not substituted in bounds of unconstrained type variables
-
- Closed
-
-
JDK-6650759 Inference of formal type parameter (unused in formal parameters) is not performed
-
- Closed
-
-
JDK-6640435 inference: propagate >> and == constraints to help uninferred type vars
-
- Closed
-
-
JDK-6371674 inference: Inferred types' bounds should help infer unconstrained type variables
-
- Closed
-
-
JDK-6559165 inference: Adherence to specification causes inference regression
-
- Closed
-