change in inference of unchecked calls after JDK-8147493
Liam Miller-Cushon
cushon at google.com
Tue Jan 26 20:09:36 UTC 2016
Thanks for the quick investigation. I wondered if this was related to
JDK-8135087 / JDK-6791481, but if the root cause is losing track of the
unchecked warning then it sounds like the similarity is superficial.
On Tue, Jan 26, 2016 at 4:36 AM, Maurizio Cimadamore <
maurizio.cimadamore at oracle.com> wrote:
>
>
> On 26/01/16 10:18, Maurizio Cimadamore wrote:
>
> I will look into this. Thanks.
>
> Update: I believe this problem has been there for a long time, but the
> fact that unchecked conversion were not propagated correctly allowed this
> program to compile (in fact, if you check with an earlier JDK 8 build,
> there are some spurious unchecked warnings generated as a result).
>
> I believe the program should be accepted - I've alpha-renamed
> type-variables in your example to make matters a bit clearer:
>
> abstract class Test {
>
> interface R<Z> {}
> interface Q<Y> {}
> interface T { <N> Q<N> n(R<N> r); }
> abstract <I> I isA(Class<I> t);
> abstract <W> S<W> w(W t);
> interface S<X> { S<X> t(X value); }
>
> void f(T t, Q<String> q) {
> w(t.n(isA(R.class))).t(q);
> }
> }
>
> The big issue occurs when we call 't.n' - performing applicability
> inference of its argument means evaluating the expression constraint isA()
> -> R<N>, and such a constraint should be evaluated by performing invocation
> type inference (18.5.2).
>
> According to 18.5.2, given that isA() returns a bare inference variable
> ('I') and given that this inference variable has an equality constraints
> (R) and given that there's no paramaterization of the target type R<N> such
> that R <: R<N>, eager instantiation of 'I' should occur.
>
> Then, following 18.5.2 we should set up a type compatibility constraints
> of the kind R -> R<N>, and that kind of compatibility constraint clearly
> generates an unchecked warning (as per 18.2.2). So, popping back, we have
> found an unchecked warning while proving applicability of 't.n'. This
> should mean that invocation type-inference for 't.n' we should effectively
> erase the return type:
>
> "If unchecked conversion was necessary for the method to be applicable
> during constraint set reduction in §18.5.1
> <https://docs.oracle.com/javase/specs/jls/se8/html/jls-18.html#jls-18.5.1>,
> the constraint formula ‹|R| → T› is reduced and incorporated with B2."
>
> Which should mean W = |Q|, and then W<Q>'s member 't' should have a type
> (Q)S<Q>, which should be compatible with Q<String>.
>
>
>
> In terms of the implementation, javac loses the unchecked warning that is
> generated when evaluating isA() -> R<N>; this means that the method call is
> not treated as unchecked.
>
> I've filed: https://bugs.openjdk.java.net/browse/JDK-8148213
>
> Maurizio
>
>
> Maurizio
>
> On 26/01/16 04:03, Liam Miller-Cushon wrote:
>
> The fix for JDK-8147493 (regression when type-checking unchecked method
> calls) prevents the following code from compiling. It is accepted by 8, and
> earlier versions of 9-dev. The return type of w(...) is now being inferred
> as S<Q<Object>>. Shouldn't the unchecked call cause return types to be
> erased?
>
> abstract class Test {
>
> interface R<E> {}
> interface Q<T> {}
> interface T { <E> Q<E> n(R<E> r); }
> abstract <T> T isA(Class<T> t);
> abstract <T> S<T> w(T t);
> interface S<T> { S<T> t(T value); }
>
> void f(T t, Q<String> q) {
> w(t.n(isA(R.class))).t(q);
> }
> }
>
>
> error: incompatible types: Q<String> cannot be converted to Q<Object>
> w(t.n(isA(R.class))).t(q);
> ^
>
> Thanks,
> Liam
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20160126/63db1dad/attachment.html>
More information about the compiler-dev
mailing list