let's consider following code:
class MyType<T> {}
class MyList<T> {
MyList<T> copyThis() { return null; }
}
class Foo<T> {
Foo(MyType<String> a){ }
}
public class Test26 {
public static void main(String argv[]) {
MyList<Foo> l1 = new MyList<>();
m2(l1, m1(
new Foo<>(new MyType()){ }
).copyThis());
}
public static <T> MyList<T> m2(MyList<T> l1, MyList<T> l2) { return null; }
public static <U> MyList<U> m1(U item) { return null; }
}
it fails to compile by javac from JDK 9 build 160 with following error:
Error:(15, 11) java: incompatible types: inference variable T has incompatible equality constraints <anonymous Foo>,Foo
But it seems that this code should compile successfully because:
1. When performing invocation type inference for m1 invocation, a temporary method is chosen according to following assertion from 18.2.1:
If the expression is a class instance creation expression or a method invocation expression, the constraint reduces to the bound set B3 which would be used to determine the expression's invocation type when targeting T, as defined in ��18.5.2. (For a class instance creation expression, the corresponding "method" used for inference is defined in ��15.9.3).
2. The temporary method return type is an anonymous class superclass as it's specified by following assertions from 15.9.3 JLS 9 draft:
... If C is an anonymous class, let D be the superclass or superinterface of C named by the class instance creation expression.
The return type of mj is ��j applied to D<F1,...,Fp>.
3. So the return type of the temporary method is Foo<F1>.
4. Unchecked conversion is necessary in order for constructor Foo to be applicable so the return type D is erased and should be Foo.
5. Thus m1 inference variable U should be inferred as Foo and m1 return type should be inferred as MyList<Foo>.
6. Finally m2 inference variable T should be inferred as Foo with no incompatible constraints.