JDK-8029718 : Should always use lambda body structure to disambiguate overload resolution
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2013-12-07
  • Updated: 2014-08-08
  • Resolved: 2014-04-22
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
8u20 b13Fixed 9Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
"Potential compatibility" is specified as follows for a lambda expression:

A lambda expression (15.27) is potentially compatible with a functional interface type (9.8) if all of the following are true:
- The arity of the targeted type's function type is the same as the arity of the lambda expression.
- If the targeted type's function type has a void return, then the lambda body is either a statement expression (14.8) or a void-compatible block (15.27.2).
- If the targeted type's function type has a (non-void) return type, then the lambda body is either an expression or a value-compatible block (15.27.2).

The current javac implementation seems to only take the lambda expression's arity into account, completely ignoring the lambda body.


 interface I { 
  String foo(String [] x, String y); 

 interface J { 
  void foo(int x, int y); 

 public class X { 
     static void goo(J j) { 
     static void goo(I i) { 
     public static void main(String[] args) throws InterruptedException { 
        goo((x, y) -> { return x[0] += 1; }); // expected: print goo(I); actual: ambiguity error

Originally reported on lambda-dev@openjdk.java.net:

Most of the current overload resolution process for lambda expressions was introduced to fix JDK-8005244

There are multiple bugs described here, and they should be addressed separately. 1) The example in the description involves the disambiguation mechanism for _implicitly-typed_ lambdas (and inexact method references). Currently, this mechanism is implemented as an arity check during applicability testing. But the correct behavior is to perform both an arity check and a more-or-less structural check of the body to ensure it is compatible with the void-ness of the targeted return. 2) The Function vs. Consumer example is not a bug. The implicitly-typed lambda 's->System.gc()' has arity 1 and a statement expression body, so it is potentially compatible with both Function and Consumer. There is, by design, no mechanism to disambiguate. 3) The Function vs. PartialFunction example (from the lambda-dev mailing list link) is (primarily) concerned with the treatment of an _explicitly-typed_ lambda when targeting two functional interface types that do or do not have wildcards. I need to look more closely at how the wildcard case is handled, but in any case there is no mechanism to disambiguate based on the 'throws' clause of a functional interface, so an ambiguity error would be expected. It is surprising that this does not happen when there are no wildcards.

check also the implications for this bug from the test case reported in: http://mail.openjdk.java.net/pipermail/lambda-dev/2014-February/011910.html

raising the priority to P2, the fix for this bug should provide a missing feature that it's important for lambda expressions, and has been noticed and reported by several users.

Another example: public class Tmp { <T> void foo(Function<String,T> function){} void foo(Consumer<String> consumer){} void test() { foo( s->System.gc() ); // javac: foo is ambiguous } } provided by Zhong Yu on lambda-dev list.

Release team: Approved for deferral.

8-defer-request: This issue is important but it's a corner case, also solving this issue is not trivial and may introduce regression issues. We think that it's better to wait till 8u20 to fix this.