Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8029718

Should always use lambda body structure to disambiguate overload resolution

    Details

    • Subcomponent:
    • Resolved In Build:
      b13
    • Verification:
      Verified

      Backports

        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.

        Example:

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

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

         public class X {
             static void goo(J j) {
                 System.out.println("goo(J)");
             }
             static void goo(I i) {
                 System.out.println("goo(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:
        http://mail.openjdk.java.net/pipermail/lambda-dev/2013-November/011394.html

          Issue Links

            Activity

            Hide
            dlsmith Dan Smith added a comment -
            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.
            Show
            dlsmith Dan Smith added a comment - 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.
            Hide
            vromero Vicente Arturo Romero Zaldivar added a comment - - edited
            Most of the current overload resolution process for lambda expressions was introduced to fix JDK-8005244
            Show
            vromero Vicente Arturo Romero Zaldivar added a comment - - edited Most of the current overload resolution process for lambda expressions was introduced to fix JDK-8005244
            Hide
            hgupdate HG Updates added a comment -
            URL: http://hg.openjdk.java.net/jdk8u/jdk8u-dev/langtools/rev/acd64168cf8b
            User: vromero
            Date: 2014-04-22 16:55:37 +0000
            Show
            hgupdate HG Updates added a comment - URL: http://hg.openjdk.java.net/jdk8u/jdk8u-dev/langtools/rev/acd64168cf8b User: vromero Date: 2014-04-22 16:55:37 +0000
            Hide
            hgupdate HG Updates added a comment -
            URL: http://hg.openjdk.java.net/jdk8u/jdk8u/langtools/rev/acd64168cf8b
            User: lana
            Date: 2014-05-05 17:28:40 +0000
            Show
            hgupdate HG Updates added a comment - URL: http://hg.openjdk.java.net/jdk8u/jdk8u/langtools/rev/acd64168cf8b User: lana Date: 2014-05-05 17:28:40 +0000
            Hide
            mkhramov Maksim Khramov added a comment -
            Verified
            Show
            mkhramov Maksim Khramov added a comment - Verified

              People

              • Assignee:
                vromero Vicente Arturo Romero Zaldivar
                Reporter:
                dlsmith Dan Smith
              • Votes:
                0 Vote for this issue
                Watchers:
                6 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: