hg: lambda/lambda/langtools: 8016175: Add bottom-up type-checking support for unambiguous method references

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Sat Jun 29 06:23:48 PDT 2013

On 29/06/13 13:59, Ali Ebrahimi wrote:
> Hi,
> On Sat, Jun 29, 2013 at 4:24 PM, maurizio cimadamore 
> <maurizio.cimadamore at oracle.com 
> <mailto:maurizio.cimadamore at oracle.com>> wrote:
>     On 28-Jun-13 5:59 PM, Ali Ebrahimi wrote:
>>     Hi Maurizio,
>>     In test MethodReference71 I don't get why g(this::m2) is ambiguous.
>>     please clarify this for me. thanks in advance.
>     It's not ambiguous, sorry for the typo in the test; however it's
>     erroneous, as the compiler doesn't have enough information to
>     type-check the method reference.
> I think this is more than typo in test case  since test output file 
> says other thing. however, I have not tried that yet.
Me bad for not opening the test - yes, the method reference is not 
ambiguous, but the enclosing method call is - so both 'g' are 
applicable, because the method reference isn't being type-checked in 
that case.
> +++ b/test/tools/javac/lambda/MethodReference71.out Fri Jun 28 
> 11:54:17 2013 +0100
> @@ -0,0 +1,3 @@
> +MethodReference71.java:24:10: compiler.err.ref.ambiguous: g, 
> kindname.method, <Z>g(MethodReference71.F<Z>), MethodReference71, 
> kindname.method, <Z>g(MethodReference71.G<Z>), MethodReference71
> +MethodReference71.java:24:11: compiler.err.prob.found.req: 
> (compiler.misc.cyclic.inference: Z)
> +2 errors
>     If, however, the method reference is unambiguous _and_ not a
>     varargs (as the first case), the compiler will go bottom up and
>     'unstick' the method reference.
>     We decided against the varargs case as, in the general case, that
>     would require support for disjunctive type inference, and we
>     wanted to limit the scope of the change at this point of the release.
> so support for this case is on the desk for future. Ya?
Well, yes - it's also a case of seeing how frequent that would be. We 
are quite confident that we should get good mileage out of current 
version, despite the limitations. The goal is to make the 'easy case' 
(which is also the most likely) work.
> what about reverse case:
> class MethodReference71b {
>  interface F<X> {
>      void m(X... x);
>  }
>  void m1(Integer i) { }
>  <Z> void g(F<Z> f) { }
>  void test() {
>      g(this::m1); //?
>  }
> }

Well, this case is erroneous; note that the method reference lookup will 
end up seraching for a method named 'm1' with an 'actual' of Z[]. Since 
there's only one 'm1' and that accepts an Integer, that's a type 
mismatch. That said, in this case the method reference is unambiguous 
and not a varargs, so it can be checked bottom up - only, doing so would 
result in a compile-time error - or at least it should, as I notice that 
your test crashes the compiler :-)


> Best Regards
> Ali Ebrahimi

More information about the lambda-dev mailing list