Anonymous class instance creation expression with diamond compatibility constraint is reduced to anonymous class type?
Georgiy Rakov
georgiy.rakov at oracle.com
Fri Mar 10 20:02:09 UTC 2017
Hello,
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.
Is it javac bug?
Thank you,
Georgiy.
-------------- next part --------------
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; }
}
More information about the compiler-dev
mailing list