javac rejects valid java 7 code

Vicente-Arturo Romero-Zaldivar vicente.romero at oracle.com
Tue Nov 19 05:01:09 PST 2013


Hi Anna,

I don't think that this is a bug. This is what javac is inferring for 
your original example:

var S
     upper bounds = A2<S1>,java.lang.Object
     lower bounds = A2<java.lang.Integer>,A2<java.lang.Long>
     eq bounds = []

var S1
     upper bounds = java.lang.Object
     lower bounds = []
     eq bounds = java.lang.Long,java.lang.Integer

all types of the form Type1, Type2 are intersection types and were 
introduced to create more correct and strict inference restrictions. In 
java7 they would have been inferred as Object, and that's why the 
example works in 7. So what javac8 is saying is that it can't find a 
solution for these variables with the given restrictions. Note that if 
in your example method bar is for example defined as:

void bar(A2<Integer> y, A2<Integer> x) {...}

then the example will compile in 8 as now it's possible to find a 
solution. The inference in that case will look like:

var S
     upper bounds = A2<S1>,java.lang.Object
     lower bounds = A2<java.lang.Integer>
     eq bounds = []
var S1
     upper bounds = java.lang.Object
     lower bounds = []
     eq bounds = java.lang.Integer

As you can see the introduction of intersection types to model bounds 
makes the compiler both smarter and stricter.

I will continue checking the rest of the examples.

Thanks,
Vicente.


On 18/11/13 15:31, Anna Kozlova wrote:
> Hi,
>
>   
>
> This code compiles with java 1.7 (also 1.6) but fails to compile with 1.8
> (b. 115)
>
>   
>
> abstract class A2<T>{
>
>      abstract <S> S foo(S x, S y);
>
>      abstract <S1> void baz(A2<S1> a)
>
>   
>
>      void bar(A2<Integer> y, A2<Long> x){
>
>           baz(foo(x, y));
>
>      }
>
> }
>
>   
>
> java: method baz in class A2<T> cannot be applied to given types;
>
>    required: A2<S1>
>
>    found: A2<capture#1 of ? extends java.lang.Number&java.lang.Comparable<?
> extends java.lang.Number&java.lang.Comparable<?>>>
>
>    reason: inferred type does not conform to equality constraint(s)
>
>      inferred: java.lang.Long
>
>      equality constraints(s): java.lang.Long,java.lang.Integer
>
>   
>
> Are these equality constraint really for S1? How does javac get them
> independently from whom they belong?
>
>   
>
> Thanks,
>
> Anna
>
>



More information about the lambda-dev mailing list