Overload resolution regression
Jonathan Ross
jonathan.ross at imc-chicago.com
Tue Nov 19 08:43:03 PST 2013
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> 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.
>
More information about the lambda-dev
mailing list