Description

"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.

Vicente Arturo Romero Zaldivar
added a comment - 2013-12-08 11:23 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.

Vicente Arturo Romero Zaldivar
added a comment - 2014-02-11 09:15 - edited 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.

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.

Dan Smith
added a comment - 2014-03-05 16:39 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.