Possible regression involving inferred generic types
Alex Buckley
alex.buckley at oracle.com
Mon Nov 4 10:53:11 PST 2013
Hi Vicente,
Thanks for identifying the JBS issue which describes the change.
If javac in JDK7 compiled this illegal code, and javac in JDK8 rejects
this illegal code, then the JBS issue should be documented as a source
compatibility issue in the JDK8 Release Notes. As examples, see the
"Tools" items in the JDK7 Release Notes at [1]. This is exactly the
place to identify changes in javac made for solid conformance reasons
which will nevertheless confuse legions of programmers.
So, please take over JDK-7115044, add the label "release-note=yes", and
add a comment showing ReproOne.java with a brief description.
Alex
[1]
http://www.oracle.com/technetwork/java/javase/compatibility-417013.html#jdk7
On 11/4/2013 7:10 AM, Vicente-Arturo Romero-Zaldivar wrote:
> Hi Liam,
>
> I have been investigating the issue you reported. The fix that changed
> javac's behavior is deep in current javac 8 repo, see [1], the original
> bug entry can be seen at [2].
>
> From my understanding of the spec and also based on Alex's answer at
> [3], I think that the fact that the code compiles in 7 is a bug and thus
> 8 can be considered correct. For this reason I don't think that there is
> a compatibility issue here.
>
> I have modified the code of ReproOne.java to:
>
> --------------------------------------------------------------------------------
>
> import java.util.List;
>
> class ReproOne {
>
> static class Baz<T> {
> public static List<Baz<Object>> getElements(Baz<Object> transcoder) {
> return null;
> }
> }
>
> private static void bar(Baz arg) {
> Baz element = Baz.getElements(arg).get(0);
> }
> }
> -----------------------------------------------------------------------------------
>
>
> Which probably shows more clearly the fact that after erasing the return
> value of getElements() to "java.util.List" the type of get(0) is Object
> and thus not assignable to a variable of type Baz.
>
> Thanks,
> Vicente.
>
> [1] http://hg.openjdk.java.net/jdk8/tl/langtools/rev/48ee63caaa93
> [2] https://bugs.openjdk.java.net/browse/JDK-7144506
> [3]
> http://mail.openjdk.java.net/pipermail/compiler-dev/2013-October/007726.html
>
>
> On 17/10/13 01:48, cushon wrote:
>> Forwarded from compiler-dev at Alex Buckley's suggestion. Original
>> thread:
>> http://mail.openjdk.java.net/pipermail/compiler-dev/2013-October/007726.html
>>
>>
>>
>> I found some cases where javac 8 behaviour diverges from javac 7, and I'm
>> interested in knowing whether this is a bug or an intentional change.
>>
>> The following programs do not compile with the jdk8 javac. (I tried
>> b111 and
>> 954dd199d6ff). All of the programs compile with the jdk7 javac.
>>
>> -------------------------------------------------------------------------------
>>
>> import java.util.List;
>>
>> class ReproOne {
>>
>> static class Baz<T> {
>> public static List<Baz<Object>> getElements(Baz<Object>
>> transcoder) {
>> return null;
>> }
>> }
>>
>> private static void bar(Baz arg) {
>> for (Baz element : Baz.getElements(arg)) {}
>> }
>> }
>> -------------------------------------------------------------------------------
>>
>> abstract class ReproTwo<T> {
>>
>> class Bar<E> {}
>>
>> T get(Bar<? extends T> arg1, Bar arg2) {
>> return circularGet(arg2, arg2);
>> }
>>
>> abstract T circularGet(final Bar<? extends T> arg1, final Bar<?>
>> arg2);
>> }
>> -------------------------------------------------------------------------------
>>
>> abstract class ReproThree<T, V> {
>>
>> class Binding<E> {}
>> class ProviderBinding<E> extends Binding<E> {}
>>
>> abstract V visitOther(Binding<? extends T> binding);
>>
>> public V visitTwo(ProviderBinding<? extends T> providerBinding) {
>> return visitOther((Binding) providerBinding);
>> }
>> }
>> -------------------------------------------------------------------------------
>>
>>
>> javac output:
>>
>> ReproOne.java:12: error: incompatible types: Object cannot be
>> converted to
>> Baz
>> for (Baz element : Baz.getElements(arg)) {}
>> ^
>>
>> ReproTwo.java:6: error: incompatible types: Object cannot be converted
>> to T
>> return circularGet(arg2, arg2);
>> ^
>> where T is a type-variable:
>> T extends Object declared in class ReproTwo
>>
>> ReproThree.java:10: error: incompatible types: Object cannot be converted
>> to V
>> return visitOther((Binding) providerBinding);
>> ^
>> where V is a type-variable:
>> V extends Object declared in class ReproThree
>>
>
More information about the compiler-dev
mailing list