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

Unable to infer correct functional interface for overloaded void method

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • None
    • 8, 9
    • tools
    • 8
    • x86
    • windows_8

      FULL PRODUCT VERSION :
      java version "1.8.0_60"
      Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
      Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 10.0.10240]

      A DESCRIPTION OF THE PROBLEM :
      Consider an overloaded method that takes two different functional interfaces as parameters (`Runnble` and `Supplier`). `System.out.println` is clearly only compatible with `Runnable`, because it is a `void` method. javac agrees, reporting an error that explicitly notes that the return type of `Supplier` cannot be converted to void. Yet javac still claims in a separate error that the call is ambiguous and matches both `Runnable` and `Supplier`.

      Note that both lambda `() -> {}` and method reference `System.out::flush` are able to resolve. The difference appears to be that `System.out.println` is overloaded with versions that take an argument. As none of those overloaded versions match either `Supplier` or `Runnable`, it is unclear how they would be relevant here.

      Another note is that this does resolve correctly and compile with the Eclipse compiler.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      >javac.exe -cp . GenericLambdas.java

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Ability to successfully compile and run. javac should select this overloaded version of wrap:
      static void wrap(Runnable function){}
      ACTUAL -
      javac is unable to compile the class

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      GenericLambdas.java:5: error: reference to wrap is ambiguous
              wrap(System.out::println);
              ^
        both method <R>wrap(Supplier<R>) in GenericLambdas and method wrap(Runnable) in GenericLambdas match
        where R is a type-variable:
          R extends Object declared in method <R>wrap(Supplier<R>)
      GenericLambdas.java:5: error: incompatible types: cannot infer type-variable(s) R
              wrap(System.out::println);
                  ^
          (argument mismatch; bad return type in method reference
            void cannot be converted to R)
        where R is a type-variable:
          R extends Object declared in method <R>wrap(Supplier<R>)
      2 errors

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
          import java.util.function.Supplier;
          
          public class GenericLambdas {
              public static void main(String[] args) {
                  wrap(System.out::println); // Compiler error here
                  wrap(() -> {}); // No error
              }
          
              static <R> void wrap(Supplier<R> function) {}
          
              static void wrap(Runnable function) {}
          }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Explicitly casting the method reference to `Runnable`:

      wrap((Runnable) System.out::println);

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: