Possible regression involving inferred generic types

Vicente-Arturo Romero-Zaldivar vicente.romero at oracle.com
Fri Nov 8 05:17:46 PST 2013


On 06/11/13 19:32, Alex Buckley wrote:
> Thanks Vicente. I believe you actually updated JDK-7144506, not 
> JDK-7115044 (the master issue for lambda expressions). BTW the title 
> for JDK-7144506 is inscrutable, so I suggest including a heading in 
> the comment for the Docs team to use. Something like "Tighter handling 
> of raw types means more return types are erased". (Please note the 
> phrase "generic method" should not appear - people seem to love using 
> it when method invocation meets parameterized types, but it is not 
> relevant here.)

Hi Alex,

Thanks for your comment, I have updated JDK-7115044, anyway I've left 
original comment in JDK-7144506 as a reference and for being related to 
the specific changeset that provoked the different behavior.

Vicente

>
> Alex
>
> On 11/6/2013 2:47 AM, Vicente-Arturo Romero-Zaldivar wrote:
>> Hi Alex,
>>
>> Thanks for the links, I have updated JDK-7115044 as you suggested,
>>
>> Vicente
>>
>> On 04/11/13 18:53, Alex Buckley wrote:
>>> 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