Change in inference behaviour after JDK-8078093
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Mon Jan 18 12:10:07 UTC 2016
Thanks for the extra examples; the first one has the same underlying
cause and is fixed by the patch I was working at.
The second failure is more subtle, and has to due with javac erroneously
caching the results of attribution inside nested class definitions that
will be thrown away - as a result we get spurious constraints mentioning
two sets of inference variables. I filed another bug for this:
https://bugs.openjdk.java.net/browse/JDK-8147546
Maurizio
On 17/01/16 00:48, Liam Miller-Cushon wrote:
> I found a couple of other changes related to the fix for JDK-8078093
> that might be distinct problems. I reported the first one as
> JI-9028659, but thought it was worth mentioning here also:
>
> 1) This is another unchecked invocation, but now it looks like target
> type inference isn't being performed on `f(null)`.
>
> abstract class Test {
>
> abstract <A> A f(A t);
> abstract <B> Class<B> g(Class<B> x, String y);
> abstract <C> void h(C t);
>
> void m(Class raw) {
> h(g(raw, f(null)));
> }
> }
>
> Test.java:8: error: method g in class Test cannot be applied to given
> types;
> h(g(raw, f(null)));
> ^
> required: Class<B>,String
> found: Class,Object
> reason: cannot infer type-variable(s) B
> (argument mismatch; Object cannot be converted to String)
> where B is a type-variable:
> B extends Object declared in method <B>g(Class<B>,String)
>
> 2)
>
> abstract class Test {
>
> interface I<O> { void t(O clazz); }
> abstract <A> I<A> a(Class<A> clazz);
> abstract <B> B b(Class<B> t);
> abstract <C> C c(C a);
>
> Object f(Iterable<Object> xs) {
> return c(c(new Object() {
> <T> void g(Class<T> clazz) {
> a(clazz).t(b(clazz));
> }
> }));
> }
> }
>
> Test.java:11: error: method t in interface I<O> cannot be applied to
> given types;
> a(clazz).t(b(clazz));
> ^
> required: T#1
> found: T#1
> reason: argument mismatch; inference variable B has incompatible bounds
> equality constraints: T#2
> upper bounds: T#1,Object
> where T#1,O,B,T#2 are type-variables:
> T#1 extends Object declared in method <T#1>g(Class<T#1>)
> O extends Object declared in interface I
> B extends Object declared in method <B>b(Class<B>)
> T#2 extends Object declared in method <T#2>g(Class<T#2>)
>
> On Fri, Jan 15, 2016 at 5:20 PM, Liam Miller-Cushon <cushon at google.com
> <mailto:cushon at google.com>> wrote:
>
> Thanks Maurizio! For what it's worth, it looks like this only
> affects a very small amount of code.
>
> On Fri, Jan 15, 2016 at 2:25 PM, Maurizio Cimadamore
> <maurizio.cimadamore at oracle.com
> <mailto:maurizio.cimadamore at oracle.com>> wrote:
>
> Hi Liam,
> it's likely a regression in handling of unchecked calls
> introduced by that fix.
>
> On a closer look, the problem seems to be caused by the fact
> that the code in Attr::checkMethod reuses the same Warner
> object (a problem that keeps biting us :-() - as the new code
> shares more state than the previous speculative-based
> implementation, the compiler ends up resetting the Warner when
> checking 'destination.get()' so that the compiler loses track
> of the fact that it had already encountered an unchecked
> warning during the applicability check of the first argument
> (Class <: Class<L>) - subsequently, the call is not flagged as
> unchecked, and a spurious inference error is then thrown.
>
> I will fix it.
>
> Filed: https://bugs.openjdk.java.net/browse/JDK-8147493
>
> Thanks
> Maurizio
>
>
> On 15/01/16 19:48, Liam Miller-Cushon wrote:
>
> It reproduces in jdk9-dev at head, and bisects to the fix
> for JDK-8078093 [1][2]. Earlier versions of javac do not
> report the error. Is this a bug?
>
> === Test.java ===
> abstract class Test {
> interface One {}
> interface Two<I extends One> { I get(); }
> interface Three<T> {}
> interface Four<T> {}
>
> <E extends Two<?>, L extends Three<E>> Four<L> f(Class
> raw, E destination) {
> return g(raw, destination.get());
> }
>
> abstract <I extends One, E extends Two<I>, L extends
> Three<E>> Four<L> g(
> Class<L> labelClass, I destinationId);
> }
> ===
>
> $ javac Test.java
> error: incompatible types: inference variable I has
> incompatible bounds
> return g(raw, destination.get());
> ^
> equality constraints: CAP#1
> lower bounds: One
> where I,E,L are type-variables:
> I extends One declared in method <I,E,L>g(Class<L>,I)
> E extends Two<I> declared in method <I,E,L>g(Class<L>,I)
> L extends Three<E> declared in method <I,E,L>g(Class<L>,I)
> where CAP#1 is a fresh type-variable:
> CAP#1 extends One from capture of ?
> 1 error
>
> [1]
> http://hg.openjdk.java.net/jdk9/dev/langtools/rev/286fc9270404
> [2] https://bugs.openjdk.java.net/browse/JDK-8078093
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20160118/183f181e/attachment-0001.html>
More information about the compiler-dev
mailing list