Overload resolution regression
Jonathan Ross
jonathan.ross at imc-chicago.com
Tue Nov 19 15:22:42 PST 2013
Ah yes, you're right. That's a relief, as the framework in question (fest
assertions) overloads pretty much every type in Assertions.assertThat(...).
It does mean that I have a lot of sloppy generics and coincidentally
working unit tests to rework.
On Tue, Nov 19, 2013 at 12:01 PM, Henry Jen <henry.jen at oracle.com> wrote:
>
>
> On 11/19/2013 08:43 AM, Jonathan Ross wrote:
> > Or a pickMe(String) for that matter?
> >
>
> You will get a compiler error on reference is ambiguous. This is why we
> end up with Comparator.comparingXXX APIs.
>
> Cheers,
> Henry
>
> > 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>
> 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> 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>> 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.
>
More information about the lambda-dev
mailing list