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