Java 9 ea154 javac compiler error - legit or bug?
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Thu Feb 23 22:16:20 UTC 2017
Phew - thanks!
Maurizio
On 23/02/17 22:05, Vitaly Davidovich wrote:
> Hi Maurizio,
>
> Just wanted to follow up and confirm that 157 fixes the issue - thanks
> again for the lightning turnaround!
>
> On Thu, Feb 9, 2017 at 5:04 PM Vitaly Davidovich <vitalyd at gmail.com
> <mailto:vitalyd at gmail.com>> wrote:
>
> Awesome - thanks!
>
> On Thu, Feb 9, 2017 at 5:03 PM Maurizio Cimadamore
> <maurizio.cimadamore at oracle.com
> <mailto:maurizio.cimadamore at oracle.com>> wrote:
>
>
> On 09/02/17 16:39, Vitaly Davidovich wrote:
>> Hi Maurizio,
>>
>> Thanks for the elaboration - much appreciated.
>>
>> Which EA build do you think will have a fix for this issue?
> I've just pushed this today, so - finger crossed - it should
> make the next one (157)
>
>
> Maurizio
>
>>
>> On Thu, Feb 9, 2017 at 8:31 AM Maurizio Cimadamore
>> <maurizio.cimadamore at oracle.com
>> <mailto:maurizio.cimadamore at oracle.com>> wrote:
>>
>> Hi Vitaly,
>> the situation is a tad convoluted; basically there's a
>> long-standing javac discrepancy which allowed javac to
>> erase the return type of an unchecked call *after* some
>> type inference has been performed. This behavior is well
>> described here:
>>
>> https://bugs.openjdk.java.net/browse/JDK-8135087
>>
>> In your example, that means that, since the first actual
>> argument to 'foo' has type Class<String> and the first
>> formal is Class<T>, javac is able to infer that T =
>> String - which gives you a fully instantiated 'foo' with
>> signature:
>>
>> String foo(Class<String> c, Collection<? super String> baz)
>>
>> Then, as an unchecked conversion has been required for
>> this method call (for the second argument), javac
>> proceeds to erase the signature - but there's nothing to
>> do! That is, erasure(String) = String, so the invocation
>> type of the inner most call has a return type 'String'.
>> That's different from what the spec says - as the spec
>> wants to erase the *declared signature* of the method if
>> an unchecked conversion occurs - in which case the
>> invocation return type would be just Object (and a
>> compiler error would be issued). This discrepancy will be
>> addressed as part of JDK 10.
>>
>> That said, JDK-8078093 accidentally introduced a change
>> in this area - in method context the current javac
>> implementation would erase the declared signature; while
>> this behavior is compatible with what the spec say, as
>> you observed, it's completely inconsistent with what
>> javac does in assignment context, and it's also
>> inconsistent with almost everything else javac does
>> (hence the weird error you get 'expected: String - found:
>> String'). This is just a plain bug - the fix for 8078093
>> was never meant to alter behavior of type-checking with
>> unchecked calls and generic methods.
>>
>> In the short term we plan to restore the original
>> behavior (as with JDK 8). In the medium term we plan to
>> get rid of this discrepancy for good.
>>
>> So, should the program compile? If you follow the spec
>> literally, no, it shouldn't. But the aim is to keep stuff
>> like this working, until we come up with a more general
>> cleanup in this area.
>>
>> I hope this clarifies the issue.
>>
>> Meanwhile, I filed this bug:
>>
>> https://bugs.openjdk.java.net/browse/JDK-8174249
>>
>> to keep track of this issue.
>>
>> Maurizio
>>
>>
>>
>> On 09/02/17 04:09, Vitaly Davidovich wrote:
>>> Hi Maurizio,
>>>
>>> Thanks for the reply. So you're saying the example
>>> using assignment context shouldn't compile either? Also,
>>> the call to 'foo' is unchecked in the wildcard argument,
>>> but it has a concrete type in the first argument. Are
>>> you saying that any unchecked param results in return
>>> type erasure?
>>>
>>> Thanks
>>>
>>> On Wed, Feb 8, 2017 at 8:38 PM Maurizio Cimadamore
>>> <maurizio.cimadamore at oracle.com
>>> <mailto:maurizio.cimadamore at oracle.com>> wrote:
>>>
>>> Hi,
>>> it seems like the behavior you observed started in
>>> b83 - as a result of this:
>>>
>>> https://bugs.openjdk.java.net/browse/JDK-8078093
>>>
>>> I believe the error is correct (although the
>>> diagnostic has always been broken since b83 in the
>>> 'verbose' mode - the non-verbose mode - w/o
>>> -Xdiags:verbose is fine). That is, the call to 'foo'
>>> is unchecked, so the return type should be erased.
>>> There seems to be an inconsistency in how javac
>>> handles this in method context compared to
>>> assignment context, and that needs to be looked at.
>>>
>>> Thanks
>>>
>>>
>>> Maurizio
>>>
>>>
>>>
>>> On 08/02/17 19:23, Vitaly Davidovich wrote:
>>>> Hi all,
>>>>
>>>> Given the following code:
>>>>
>>>> import java.util.ArrayList;
>>>> import java.util.Collection;
>>>>
>>>> public class Foo {
>>>> static <T> T foo(Class<T> c, Collection<? super T>
>>>> baz) {
>>>> return null;
>>>> }
>>>>
>>>> static void bar(String c) {
>>>>
>>>> }
>>>>
>>>> @SuppressWarnings("unchecked")
>>>> public static void main(String[] args) {
>>>> // this works
>>>> bar(foo(String.class, new ArrayList<String>()));
>>>>
>>>> // this works with a warning
>>>> String s = foo(String.class, new ArrayList());
>>>> bar(s);
>>>>
>>>> // this causes an error on JDK9
>>>> bar(foo(String.class, new ArrayList()));
>>>> }
>>>> }
>>>>
>>>> javac 9-ea (build 9-ea+154) fails with this
>>>> interesting error (on the last line in main, as the
>>>> comments there indicate):
>>>>
>>>> Foo.java:23: error: method bar in class Foo cannot
>>>> be applied to given types;
>>>> bar(foo(String.class, new ArrayList()));
>>>> ^
>>>> required: String
>>>> found: String
>>>> reason: argument mismatch; Object cannot be
>>>> converted to String
>>>> 1 error
>>>>
>>>> Java 8 compiles fine, and the other 2 lines compile
>>>> in the same java 9 build as well.
>>>>
>>>> Is this a javac bug or legit? It seems like a
>>>> compiler error. At a minimum, the diagnostic
>>>> output "required String, found String" is confusing.
>>>>
>>>> Thanks
>>>>
>>>>
>>>
>>> --
>>> Sent from my phone
>>
>> --
>> Sent from my phone
>
> --
> Sent from my phone
>
> --
> Sent from my phone
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20170223/cbdf0876/attachment-0001.html>
More information about the compiler-dev
mailing list