Overload resolution regression
Paul Benedict
pbenedict at apache.org
Tue Nov 19 07:02:30 PST 2013
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
More information about the lambda-dev
mailing list