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