Overload resolution regression
Vicente-Arturo Romero-Zaldivar
vicente.romero at oracle.com
Tue Dec 17 10:29:52 PST 2013
Hi Jonathan,
In both cases we have nested invocation that returns an inference variable.
I added the test case explicitly because if it's the case that both test
cases don't have the same root cause then they both will be addressed
anyway.
Thanks,
Vicente
On 17/12/13 17:19, Jonathan Ross wrote:
> Hi Vincente,
>
> Thanks for adding the test case. The original code example in
> JDK-8028774 <https://bugs.openjdk.java.net/browse/JDK-8028774> was
> mine as well, by the way. It would appear to be a slightly different
> issue, at least the compiler error is different. With the new test
> case, we get:
>
>
> $ javac Test.java
> Test.java:10: error: reference to use is ambiguous
> use(build());
> ^
> both method use(Collection<?>) in Test and method use(Double) in
> Test match
> 1 error
>
>
> What leads you to think it is the same issue?
>
> — Jonathan
>
> On Dec 17, 2013, at 9:06 AM, Vicente-Arturo Romero-Zaldivar
> <vicente.romero at oracle.com <mailto:vicente.romero at oracle.com>> wrote:
>
>> Hi Jonathan,
>>
>> Thanks for the provided test case. I think that this is a bug in
>> javac. The bug has been filed before,
>> https://bugs.openjdk.java.net/browse/JDK-8028774, for similar cases.
>> I have added your test case to the bug entry.
>>
>> Thanks,
>> Vicente
>>
>> On 13/12/13 20:38, Jonathan C. Ross wrote:
>>> Hi again,
>>>
>>> I thought I understood this issue after Remi’s explanation, but I
>>> have run into a couple of cases where I still don’t understand the
>>> outcome, One example is essentially para-phrased as follows:
>>>
>>> import java.util.Collection;
>>>
>>> abstract class Test {
>>> abstract <T extends Collection<?>> T build();
>>>
>>> abstract void use(Collection<?> n);
>>> abstract void use(Double s);
>>>
>>> void f() {
>>> use(build());
>>> }
>>> }
>>>
>>> Works fine in 7, and my JDK-8-savvy IDE’s (IntelliJ, Netbeans) think
>>> it’s fine. However, ea-b119 thinks the overloading of ‘use' is
>>> ambiguous. In what scenario could this behaviour be an enhancement?
>>>
>>> — Jonathan Ross
>>>
>>>
>>> On 19 Nov 2013, at 10:43, Jonathan Ross
>>> <jonathan.ross at imc-chicago.com
>>> <mailto:jonathan.ross at imc-chicago.com>> wrote:
>>>
>>>> Or a pickMe(String) for that matter?
>>>>
>>>> Thanks for the explanation, Remi. Indeed, we were just using the
>>>> coincidence of the Object fallback; it seems to predominantly
>>>> affect our
>>>> test fixtures - I hope, at least. The nasty thing about it is that it
>>>> leads to a runtime exception rather than a compilation error, so we
>>>> may not
>>>> find out for certain for a while.
>>>>
>>>>
>>>> On Tue, Nov 19, 2013 at 9:02 AM, Paul Benedict
>>>> <pbenedict at apache.org <mailto:pbenedict at apache.org>> wrote:
>>>>
>>>>> Ah, okay, that makes sense now. Filling me in on the background
>>>>> was a big
>>>>> helper.
>>>>>
>>>>> For the sake of clarity, what would happen to Jonathan's example
>>>>> if there
>>>>> was also a third pickMe(BigDecimal)?
>>>>>
>>>>>
>>>>> On Tue, Nov 19, 2013 at 8:39 AM, Remi Forax <forax at univ-mlv.fr
>>>>> <mailto:forax at univ-mlv.fr>> wrote:
>>>>>
>>>>>> On 11/19/2013 02:53 PM, Paul Benedict wrote:
>>>>>>
>>>>>>> I don't see how you can call the compiler "smarter" in this example.
>>>>>>>
>>>>>> 'smarter' because this is not the only use case :)
>>>>>> Here is an example that fails to compile with 7 but compiles with 8
>>>>>> (comparingByValue is also a method that only uses type variables to
>>>>>> specify the return type)
>>>>>> Map<String,String> map = ...
>>>>>> map.entrySet().stream().sorted(Map.Entry.comparingByValue());
>>>>>>
>>>>>> For pickMe(unsafe()) the inference fails in 7 and uses Object as a
>>>>>> fallback,
>>>>>> it appears that it's what the user want but that's just a
>>>>>> coincidence.
>>>>>>
>>>>>> It is choosing pickMe(BigInteger) without >: BigInteger type being
>>>>>>> present.
>>>>>>>
>>>>>>
>>>>>> Don't forget that pickMe(null) also choose pickMe(BigInteger),
>>>>>> it's the way the algorithm that choose the most specific method works
>>>>>> since the beginning.
>>>>>> here, the constraint is that T is a subtype of Object, so both
>>>>>> pickMe(Object) and pickMe(BigInteger) are applicable,
>>>>>> then the most specific algorithm chooses that pickMe(BigInteger) is
>>>>> better
>>>>>> than pickMe(Object).
>>>>>>
>>>>>> cheers,
>>>>>> Rémi
>>>>>>
>>>>>>
>>>>>>> On Tue, Nov 19, 2013 at 5:30 AM, Remi Forax <forax at univ-mlv.fr
>>>>>>> <mailto:forax at univ-mlv.fr> <mailto:
>>>>>>> forax at univ-mlv.fr <mailto:forax at univ-mlv.fr>>> wrote:
>>>>>>>
>>>>>>> On 11/19/2013 01:43 AM, Jonathan Ross wrote:
>>>>>>>> Hi,
>>>>>>> Hi Johnathan,
>>>>>>>
>>>>>>>> I recently started porting a 150k-line project to jdk 8 to try
>>>>>>> my hand at
>>>>>>>> the recent changes in the collection libraries. (Hadn't done
>>>>>>> this since
>>>>>>>> last year, my apologies!)
>>>>>>>>
>>>>>>>> I have run in to a large number of compilation errors:
>>>>>>> regressions in type
>>>>>>>> inference and overload resolution. A lot of these are in unit
>>>>>>> tests using
>>>>>>>> mockito and fest and other similar monadic apis that rely heavily
>>>>> on
>>>>>>>> overload resolution.
>>>>>>> It's not a regression, it's an enhancement :)
>>>>>>>
>>>>>>>> The code snippet below is a distilled version of my typical
>>>>>>> compilation
>>>>>>>> error: our test code relying on the compiler choosing the Object
>>>>>>> overload
>>>>>>>> by default.
>>>>>>>>
>>>>>>>>
>>>>>>>> import java.math.BigInteger;
>>>>>>>>
>>>>>>>> public class OverloadingRegression {
>>>>>>>>
>>>>>>>> static <T> T unsafeCast(Object anObject) {
>>>>>>>> return (T) anObject;
>>>>>>>> }
>>>>>>>>
>>>>>>>> public void showOverloadResolutionIssue() {
>>>>>>>> pickMe(unsafeCast(new String()));
>>>>>>>> }
>>>>>>>>
>>>>>>>> private void pickMe(BigInteger o) { /* ClassCastException in
>>>>>>>> 1.8.0-ea-b115 */ }
>>>>>>>>
>>>>>>>> private void pickMe(Object o) { /* fine, picked in 1.6 &
>>>>>>> 1.7 */ }
>>>>>>>> }
>>>>>>>>
>>>>>>>>
>>>>>>>> Obviously the unsafeCast is not going to win any beauty prizes,
>>>>> but
>>>>>>>> sometimes you just have to do this sort of thing. My main point
>>>>>>> is: it
>>>>>>>> used to work in java 7, it doesn't any more.
>>>>>>>>
>>>>>>>> Is this a known issue (or is it even expected behaviour)?
>>>>>>> Yes, it's the expected behavior, when you try do inference
>>>>>>> inside a
>>>>>>> method call,
>>>>>>> here unsafeCast is inside pickMe, in that case with jdk6 & 7, the
>>>>>>> inference
>>>>>>> is not done and T is replaceb by its bound (Object), with
>>>>>>> jdk8, the
>>>>>>> compiler is smarter,
>>>>>>> and find the most specific method first, here pickMe(BigInteger)
>>>>>>> is more
>>>>>>> specific than pickMe(Object) and then infers T (T = BigInteger).
>>>>>>>
>>>>>>>> I'm using 1.8.0-ea-b115, but I verified that it fails with all
>>>>>>> 1.8 jdks I
>>>>>>>> have my box. When I pass in -source 1.7 it does work. And when
>>>>>>> I do an
>>>>>>>> explicit cast to Object (of course).
>>>>>>> so this is the correct behavior for 8, the new stream API heavily
>>>>>>> relies
>>>>>>> on that,
>>>>>>> and yes, this new semantics is not compatible with 1.7 in the
>>>>>>> case
>>>>> the
>>>>>>> inference was failing,
>>>>>>> this is a known compatibility issue.
>>>>>>>
>>>>>>>> -- Jonathan Ross
>>>>>>>>
>>>>>>> cheers,
>>>>>>> Rémi
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Cheers,
>>>>>>> Paul
>>>>>>>
>>>>>>
>>>>>
>>>>> --
>>>>> Cheers,
>>>>> Paul
>>>>>
>>>>>
>>>>> ________________________________
>>>>>
>>>>> The information in this e-mail is intended only for the person or
>>>>> entity
>>>>> to which it is addressed.
>>>>>
>>>>> It may contain confidential and /or privileged material. If
>>>>> someone other
>>>>> than the intended recipient should receive this e-mail, he / she
>>>>> shall not
>>>>> be entitled to read, disseminate, disclose or duplicate it.
>>>>>
>>>>> If you receive this e-mail unintentionally, please inform us
>>>>> immediately
>>>>> by "reply" and then delete it from your system. Although this
>>>>> information
>>>>> has been compiled with great care, neither IMC Financial Markets &
>>>>> Asset
>>>>> Management nor any of its related entities shall accept any
>>>>> responsibility
>>>>> for any errors, omissions or other inaccuracies in this
>>>>> information or for
>>>>> the consequences thereof, nor shall it be bound in any way by the
>>>>> contents
>>>>> of this e-mail or its attachments. In the event of incomplete or
>>>>> incorrect
>>>>> transmission, please return the e-mail to the sender and
>>>>> permanently delete
>>>>> this message and any attachments.
>>>>>
>>>>> Messages and attachments are scanned for all known viruses. Always
>>>>> scan
>>>>> attachments before opening them.
>>>>>
>>>
>>> ________________________________
>>>
>>> The information in this e-mail is intended only for the person or
>>> entity to which it is addressed.
>>>
>>> It may contain confidential and /or privileged material. If someone
>>> other than the intended recipient should receive this e-mail, he /
>>> she shall not be entitled to read, disseminate, disclose or
>>> duplicate it.
>>>
>>> If you receive this e-mail unintentionally, please inform us
>>> immediately by "reply" and then delete it from your system. Although
>>> this information has been compiled with great care, neither IMC
>>> Financial Markets & Asset Management nor any of its related entities
>>> shall accept any responsibility for any errors, omissions or other
>>> inaccuracies in this information or for the consequences thereof,
>>> nor shall it be bound in any way by the contents of this e-mail or
>>> its attachments. In the event of incomplete or incorrect
>>> transmission, please return the e-mail to the sender and permanently
>>> delete this message and any attachments.
>>>
>>> Messages and attachments are scanned for all known viruses. Always
>>> scan attachments before opening them.
>>>
>>
>
>
> ------------------------------------------------------------------------
>
> The information in this e-mail is intended only for the person or
> entity to which it is addressed.
>
> It may contain confidential and /or privileged material. If someone
> other than the intended recipient should receive this e-mail, he / she
> shall not be entitled to read, disseminate, disclose or duplicate it.
>
> If you receive this e-mail unintentionally, please inform us
> immediately by "reply" and then delete it from your system. Although
> this information has been compiled with great care, neither IMC
> Financial Markets & Asset Management nor any of its related entities
> shall accept any responsibility for any errors, omissions or other
> inaccuracies in this information or for the consequences thereof, nor
> shall it be bound in any way by the contents of this e-mail or its
> attachments. In the event of incomplete or incorrect transmission,
> please return the e-mail to the sender and permanently delete this
> message and any attachments.
>
> Messages and attachments are scanned for all known viruses. Always
> scan attachments before opening them.
More information about the lambda-dev
mailing list