Java 9 ea154 javac compiler error - legit or bug?

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Thu Feb 9 22:03:13 UTC 2017


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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20170209/274f1b02/attachment-0001.html>


More information about the compiler-dev mailing list