[jvm-l] Newly introduced OpenJDK javac bug?
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Fri Jun 10 08:54:16 PDT 2011
Hi Charles,
we're definitively out of time to be playing with overload resolution at
this stage. Note that the old javac algorithm for most specific was
working 'by accident' - moreover, when performing the most specific
check, javac ended up comparing the underlying method signatures with
the varargs parameter turned into an array, thus leading to even more
confusion. All this to say that changing the spec to match the old javac
behavior is out of question.
Going forward, we might have room to revise the most specific varargs
algorithm as currently specified, so that it will give an answer that
might be more intuitive for developers. In my opinion, the root of all
the problems is the fact that the most specific algorithm for varargs
invocation uses straight subtyping checks (<:) instead of method
conversion checks. This point-wise change would enable javac to accept
example like yours (but we should check with our spec gurus ;-) ).
Maurizio
On 10/06/11 16:20, Charles Oliver Nutter wrote:
> Re-posting this back to compiler-dev to see if there's any chance of
> fixing this before Java 7 (assuming the answer is "no"). See my
> analysis below Neal's response. Even if it's impossible to get in, I'd
> like to play with the idea a bit and see if it feels like a correct
> change for some time in the future.
>
> - Charlie
>
> On Fri, Jun 10, 2011 at 10:01 AM, Neal Gafter<neal at gafter.com> wrote:
>> Charles-
>>
>> This makes a lot of sense. My concern is that such a change may break an
>> unknown number of other, different examples.
>>
>> Rather than trying to construct an overload resolution algorithm that makes
>> this example work as expected, I think the right solution would be to
>> characterize what javac used to do. If that characterization is as
>> straightforward as the current specification, then the spec (rather than the
>> compiler) ought to be adjusted.
>>
>> However, unless someone at Oracle does this quite soon, I fear it is a lost
>> cause, as SE 7 is about to be unleashed.
>>
>> Cheers,
>> Neal
>>
>> On Thu, Jun 9, 2011 at 9:49 PM, Charles Oliver Nutter<headius at headius.com>
>> wrote:
>>> It would probably help to spell out the paths through specificity
>>> separately, rather than have everyone try to parse the rules, but it
>>> seems that Integer fits the subclass match *without* a method
>>> invocation conversion, and therefore Object is a better fit. As I said
>>> previously, a match via conversion should be considered of lower
>>> desirability than a match that does not require conversion. That makes
>>> both cases work.
>>>
>>> * primitive => primitive outweighs primitive => reference because a
>>> conversion is required (int => int preferred over int => Object or int
>>> => Integer)
>>> * boxed => object outweighs boxed => primitive because a conversion is
>>> required (Integer => Object or Integer => Integer preferred over
>>> Integer => int)
>>>
>>> For my benefit and the benefit of others, let me try to spell it out.
>>>
>>> What you're saying by "the input doesn't matter" is that the
>>> specificity tests are done independent of the actual incoming argument
>>> types. A set of matching methods is found based on the incoming types,
>>> and then that pool of methods enters the octagon with hopefully only
>>> one "most specific" winner emerging. That's true. However, going back
>>> to my earlier email, specificity is currently based subclass
>>> relationships. Subclass relationships do not make sense in the context
>>> of primitives, so we're using subclass specificity tests to choose a
>>> method for an incoming argument type that doesn't subclass and doesn't
>>> even live in the type hierarchy we're using to determine specificity.
>>>
>>> And if I continue from that understanding, what you mean by "int can't
>>> be both more and less specific than Integer" is that without knowledge
>>> of the actual incoming types, you can't make a rule whether to use the
>>> int signature or the Integer signature in a way consistent with how we
>>> want both int and Integer inputs to work. If you say int> Integer so
>>> that int inputs choose int signatures, then you can't get to say
>>> Integer> int when a later Integer call should call the Integer
>>> signature.
>>>
>>> I think Dan Smith has it right when he said we need to insert a phase:
>>>
>>> 1) Applicable by subtyping
>>> 2) Applicable by method invocation
>>> *3) Applicable by subtyping with varargs*
>>> 4) Applicable by method invocation with varargs
>>>
>>> This allows my original example to resolve the way most here think it
>>> should. It also allows Integer to go to Object as appropriate. It's
>>> not perfect though.
>>>
>>> Original example
>>>
>>> void method(String s, int n, Object... os);
>>> void method(String s, Object... os);
>>> method("abc", 3);
>>>
>>> Resolves to the int, Object... signature as expected. But Dan pointed
>>> out that the same example with Integer would behave differently.
>>>
>>> void method(String s, int n, Object... os);
>>> void method(String s, Object... os);
>>> method("abc", new Integer(3));
>>>
>>> Currently this is ambiguous since we go immediately to resolution
>>> using conversion *and* varargs. Both int, Object... and Object...
>>> signatures enter the octagon. Under the new four-phase mechanism, it
>>> would resolve to the Object... signature because subtyping + varargs
>>> takes precedence over conversion + varargs, resulting in the Object...
>>> signature entering the octagon at the new phase three.
>>>
>>> This is a change, but it's more consistent with the first two
>>> phases...and of course since it was ambiguous before, no code like
>>> this exists in the wild. Given another example that does not hit
>>> varargs:
>>>
>>> void method(String s, int n);
>>> void method(String s, Object os);
>>> method("abc", new Integer(3));
>>>
>>> Obviously the Object signature is chosen for exactly the same reason:
>>> subclassing rules over conversion. And people expect this. So rather
>>> than making selection inconsistent, it actually makes the varargs
>>> phases more consistent with the non-varargs phases.
>>>
>>> Why shouldn't varargs phase(s) obey the same precedence of subclassing
>>> over conversion?
>>>
>>> - Charlie
>>>
>>> On Thu, Jun 9, 2011 at 5:44 PM, Neal Gafter<neal at gafter.com> wrote:
>>>> The input doesn't matter to Java's "more specific" test.
>>>>
>>>> What if the input is Integer and the choices are int and Object. Do you
>>>> really prefer the NullPointerException-causing unboxing conversion to
>>>> the
>>>> safe widening reference conversion?
>>>>
>>>> On Thu, Jun 9, 2011 at 3:30 PM, Charles Oliver Nutter
>>>> <headius at headius.com>
>>>> wrote:
>>>>> On Thu, Jun 9, 2011 at 5:12 PM, Rémi Forax<forax at univ-mlv.fr> wrote:
>>>>>> You can, just consider int and Integer has the same node:
>>>>>> int<= Integer&& int>= Integer because int == Integer
>>>>> In addition, I don't see how Integer would ever need to be considered
>>>>> more specific than int, for an int input. In what case does that
>>>>> happen?
>>>>>
>>>>> - Charlie
>>>>>
>>>>> --
>>>>> 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.
>>>>> To unsubscribe from this group, send email to
>>>>> jvm-languages+unsubscribe at googlegroups.com.
>>>>> For more options, visit this group at
>>>>> http://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.
>>>> To unsubscribe from this group, send email to
>>>> jvm-languages+unsubscribe at googlegroups.com.
>>>> For more options, visit this group at
>>>> http://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.
>>> To unsubscribe from this group, send email to
>>> jvm-languages+unsubscribe at googlegroups.com.
>>> For more options, visit this group at
>>> http://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.
>> To unsubscribe from this group, send email to
>> jvm-languages+unsubscribe at googlegroups.com.
>> For more options, visit this group at
>> http://groups.google.com/group/jvm-languages?hl=en.
>>
More information about the compiler-dev
mailing list