Change in inference behaviour after JDK-8078093

Liam Miller-Cushon cushon at google.com
Sun Jan 17 00:48:54 UTC 2016


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>
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> 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/20160116/54eb252d/attachment-0001.html>


More information about the compiler-dev mailing list