Inference of recursive types

Liam Miller-Cushon cushon at google.com
Fri Feb 21 13:09:59 PST 2014


I was surprised that it starts working again with javac 8 source 8, but I
appreciate that it may not be a regression. Thanks for investigating.

Liam


On Fri, Feb 21, 2014 at 1:02 PM, Vicente-Arturo Romero-Zaldivar <
vicente.romero at oracle.com> wrote:

> On 21/02/14 19:31, Liam Miller-Cushon wrote:
>
>> +lambda-dev
>>
>> Any thoughts on this?
>>
>
> Hi Liam,
>
> I will look at this and get back to you. The fact that something is
> working find in 7 and not in 8 source 7 doesn't imply that there is a
> regression in the compiler. It can be a bug in 7 that we don't have to
> reproduce in 8 just to keep the compatibility. Every case is different and
> this could be a regression.
>
> Thanks,
> Vicente
>
>
>
>> This affects a significant amount of code, and the fact that it only
>> appears when compiling java 7 with javac8 makes it look like a regression.
>>
>> The following is a less contrived example of code with recursive types
>> that
>> doesn't currently compile with javac8 -source 7 -target 7:
>>
>> class Test {
>>    <T extends Enum<T>> T getEnum() { return null; }
>>    <U extends Enum<U>> void m() {
>>      U e = getEnum();
>>    }
>> }
>>
>> $ javac -source 7 -target 7 Test.java
>> Test.java:4: error: incompatible types: inference variable T#1 has
>> incompatible upper bounds Enum<T#2>,U
>>      U e = getEnum();
>>                   ^
>>    where T#1,T#2,U are type-variables:
>>      T#1 extends Enum<T#1> declared in method <T#1>getEnum()
>>      T#2 extends U
>>      U extends Enum<U> declared in method <U>m()
>>
>> On Fri, Feb 14, 2014 at 5:07 PM, Liam Miller-Cushon <cushon at google.com
>> >wrote:
>>
>>  Hi -
>>>
>>> Sorry if this has already been discussed, but I ran into a difference in
>>> behaviour between javac8 -source 7/-target 7 and both javac7 and javac8
>>> -source 8/-target 8.
>>>
>>> The following program compiles with everything except javac8 -source
>>> 7/-target 7.
>>>
>>> Is this an intentional change? Having to make g's type parameter explicit
>>> feels like a regression.
>>>
>>> ===
>>> class Test {
>>>    static class One<T> {}
>>>    static class Two extends One<Two> {}
>>>
>>>    <T extends One<T>> T f(T a, String s) {
>>>      T t = g(s);
>>>      return t;
>>>    }
>>>    static <U extends One<U>> U g(String s) {
>>>      throw new RuntimeException();
>>>    }
>>> }
>>> ===
>>>
>>> Test.java:6: error: incompatible types: inference variable U#1 has
>>> incompatible upper bounds One<U#2>,T
>>>      T t = g(s);
>>>             ^
>>>    where U#1,U#2,T are type-variables:
>>>      U#1 extends One<U#1> declared in method <U#1>g(String)
>>>      U#2 extends T
>>>      T extends One<T> declared in method <T>f(T,String)
>>>
>>>
>


More information about the lambda-dev mailing list