Fwd: [jvm-l] Newly introduced OpenJDK javac bug?

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Thu Jun 9 08:30:28 PDT 2011


On 09/06/11 15:52, Robert Fischer wrote:
> I've been using precisely the pattern that Charlie lays out in some of 
> my code, as well, so I'm going to have to code around it now. I didn't 
> realize that it was technically ambiguous — it's really surprising to 
> my intuition, which (I'm now realizing as I think about it) tries to 
> match arguments left to right, and only drops to varargs if it can't 
> find a match. That intuition is obviously wrong compared to the spec, 
> but does that mean we have a bug in the spec? What's the justification 
> for this behavior?
This seems to be an area where things can be improved. Note that the JDK 
7 algorithm has been brought in sync with the spec because we had other 
bugs in which the compiler was issuing bad error messages (esp. with 
varargs with primitive types, see [1] and related issues).

[1] - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6199075

Maurizio
>
> For the record, both Scala and Groovy resolve methods more in line 
> with intuition:
> Groovy > https://gist.github.com/1016878
> Scala > https://gist.github.com/1016880
>
> ~~ Robert.
>
> On Thu, Jun 9, 2011 at 10:36 AM, Charles Oliver Nutter 
> <headius at headius.com <mailto:headius at headius.com>> wrote:
>
>     I accept this analysis as written. I do however have a few
>     questions/comments.
>
>     * This seems like it only affects cases where you have primitives
>     butting up against a varargs Object..., correct? Only in those
>     cases do you have a method invocation conversion from a type that
>     does not subclass Object. Edge-casey.
>
>     * It is unexpected, albeit correct according to specification. A
>     few reasons:
>
>     ** The int => Object conversion is via Integer, which *is* a
>     subtype relationship. I know the spec does not provide for
>     reevaluating specificity after a method invocation
>     conversion...but perhaps it should.
>
>     ** int *is* more specific than Object from a
>     programmer/development perspective. Another way of looking at
>     specificity would be "fewer combinations of argument types apply".
>     That's clearly the case here.
>
>     I suspect I won't be the only one to run into this new behavior.
>     As it stands, the methods in question in JRuby no longer need the
>     varargs forms, so I'm removing them.
>
>     - Charlie
>
>     On Thu, Jun 9, 2011 at 9:24 AM, Maurizio Cimadamore
>     <maurizio.cimadamore at oracle.com
>     <mailto:maurizio.cimadamore at oracle.com>> wrote:
>
>         Remi, your analysis is correct.
>
>         Consider the method call:
>
>         method("str", 1);
>
>         Now, you have two potentially applicable methods, namely
>
>         - method(String str, int num, Object... data)
>         - method(String str, Object... data)
>
>         Since both are varargs method, both methods can only be
>         applicable by variable arity method conversion (see JLS
>         15.12.2.4). Both methods are applicable (note that the second
>         method is applicable since there exist a method invocation
>         conversion to go from int to Object).
>
>         Since both are applicable we have now to choose the most
>         specific (see 15.12.2.5) - the rules says that:
>
>         "In addition, one variable arity member method named m is more
>         specific than another variable arity member method of the same
>         name if either:
>
>         *) One member method has n parameters and the other has k
>         parameters, where n >= k. The types of the parameters of the
>         first member method are T1, . . . , Tn-1 , Tn[], the types of
>         the parameters of the other method are U1, . . . , Uk-1, Uk[].
>         [...] otherwise let Si = Ui, 1 < i <=k. Then:
>
>            - for all j from 1 to k-1, Tj <: Sj, and,
>            - for all j from k to n, Tj <: Sk, and,
>
>         *) One member method has k parameters and the other has n
>         parameters, where n>=k. The types of the parameters of the
>         first method are U1, . . . , Uk-1, Uk[], the types of the
>         parameters of the other method are T1, . . ., Tn-1, Tn[].
>         [...] otherwise let Si = Ti, 1 <i <= n. Then:
>
>            - for all j from 1 to k-1 , Uj <: Sj, and,
>            - for all j from k to n , Uk <: Sj, and,"
>
>         *** Part 1
>
>         So, is M1 = method(String str, int num, Object... data) more
>         specific than M2 = method(String str, Object... data) ? Since
>         arity of M1 is bigger than arity of M2, the first bullet
>         apply. More specifically, n is 3, k is 2, T = { String, int,
>         Object }, while S = U = { String, Object }. We have to prove that:
>
>            - for all j from 1 to 1 (as k is 2), Tj <: Sj, and,
>            - for all j from 2 to 3, Tj <: S2, and,
>
>         Which means:
>
>         j = 1 --> T1 <: S1 ? Yes, because String <: String
>         j = 1 --> T2 <: S2 ? No, because int is not a subtype of Object
>
>         Which means method(String str, int num, Object... data) is not
>         more specific than method(String str, Object... data). Let's
>         try the other way around.
>
>         *** Part 2
>
>         So, is M1 = method(String str, Object... data) more specific
>         than M2 = method(String str, int i, Object... data) ? Since
>         arity of M1 is smaller than arity of M2, the second bullet
>         apply. More specifically, n is 2, k is 3, U = { String, Object
>         }, S = T = { String, int, Object }. We have to prove that:
>
>            - for all j from 1 to 2 (as k is 3), Uj <: Sj, and,
>            - for all j from 3 to 3, Uj <: S3, and,
>
>         Which means:
>
>         j = 1 --> U1 <: S1 ? Yes, because String <: String
>         j = 1 --> U2 <: S2 ? No, because int is not a subtype of Object
>
>         Which means method(String str, Object... data) is not more
>         specific than method(String str, int i, Object... data). The
>         conclusion is that neither method is more specific than the
>         other, so the compile-time error is legitimate.
>
>         Maurizio
>
>
>
>
>         On 09/06/11 14:51, Rémi Forax wrote:
>>         add compiler dev-list to the loop.
>>
>>         My analysis is that this is a fix for a previously existing bug,
>>         so the behavior of javac is now correct.
>>
>>         With method("str", 1), no method are applicable without
>>         considering boxing and varargs,
>>         so we ends up with phase 3. Here, both boxing and varargs are
>>         enabled so
>>         the two method are applicable and not one is most specific.
>>         So the call is ambiguous.
>>
>>         Rémi
>>
>>         -------- Original Message --------
>>         Subject: 	[jvm-l] Newly introduced OpenJDK javac bug?
>>         Date: 	Thu, 9 Jun 2011 08:26:04 -0500
>>         From: 	Charles Oliver Nutter <headius at headius.com>
>>         <mailto:headius at headius.com>
>>         Reply-To: 	jvm-languages at googlegroups.com
>>         <mailto:jvm-languages at googlegroups.com>
>>         To: 	JVM Languages <jvm-languages at googlegroups.com>
>>         <mailto:jvm-languages at googlegroups.com>
>>         CC: 	Mark Reinhold <mark.reinhold at oracle.com>
>>         <mailto:mark.reinhold at oracle.com>
>>
>>
>>
>>         Recent OpenJDK 7 builds seem to have introduced a bug into javac.
>>         Correct me if I'm wrong.
>>
>>         https://gist.github.com/1016436
>>
>>         public class Foo {
>>              public static void main(String[] args) {
>>         	method("str");
>>         	method("str", 1);
>>         	method("str", 1, "data");
>>              }
>>
>>              public static void method(String str, int num, Object... data) {
>>         	// do nothing
>>              }
>>
>>              public static void method(String str, Object... data) {
>>         	// do nothing
>>              }
>>         }
>>
>>         It seems that the order in which it attempts to apply varargs and
>>         boxing has changed. On OpenJDK/Hotspot 1.6.x and OpenJDK 7 builds
>>         prior to 143, this compiles fine and calls the first signature for all
>>         calls. My interpretation of the Java specification is that this is
>>         correct behavior; the more exact signature that requires no boxing is
>>         chosen rather than the second signature which does require boxing.
>>
>>         However on later builds, we get the following errors for this case:
>>
>>         Foo.java:4: error: reference to method is ambiguous, both method
>>         method(String,int,Object...) in Foo and method
>>         method(String,Object...) in Foo match
>>         	method("str", 1);
>>         	^
>>         Foo.java:5: error: reference to method is ambiguous, both method
>>         method(String,int,Object...) in Foo and method
>>         method(String,Object...) in Foo match
>>         	method("str", 1, "data");
>>
>>         Both invocations fall through to phase 3 of method selection, variable
>>         arity. But in this case, I believe the first signature (with int)
>>         should resolve as "more specific" than the second, and should be
>>         chosen for both invocations. I admit it's a grey area, however, and I
>>         can't find a specific clause in the Java spec to back me up.
>>
>>         I'm not sure who to talk to about this, or whether I'm right in
>>         thinking this is a new bug in javac. Thoughts?
>>
>>         - Charlie
>>
>>         -- 
>>         You received this message because you are subscribed to the Google Groups "JVM Languages" group.
>>         To post to this group, send email tojvm-languages at googlegroups.com  <mailto:jvm-languages at googlegroups.com>.
>>         To unsubscribe from this group, send email tojvm-languages+unsubscribe at googlegroups.com  <mailto:jvm-languages+unsubscribe at googlegroups.com>.
>>         For more options, visit this group athttp://groups.google.com/group/jvm-languages?hl=en.
>>
>
>
>     -- 
>     You received this message because you are subscribed to the Google
>     Groups "JVM Languages" group.
>     To post to this group, send email to
>     jvm-languages at googlegroups.com
>     <mailto:jvm-languages at googlegroups.com>.
>     To unsubscribe from this group, send email to
>     jvm-languages+unsubscribe at googlegroups.com
>     <mailto:jvm-languages%2Bunsubscribe at googlegroups.com>.
>     For more options, visit this group at
>     http://groups.google.com/group/jvm-languages?hl=en.
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20110609/82caf335/attachment.html 


More information about the compiler-dev mailing list