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

Incorrect "ambiguous method invocation" error

XMLWordPrintable

    • x86_64
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      openjdk full version "12-ea+19"

      A DESCRIPTION OF THE PROBLEM :
      In the reproducer, I have a class with 2 overloaded methods named "pipe", one taking a Function, the other a Consumer. javac says that both methods are applicable when passing "System.out::println" as an argument. However, I don't see how "System.out::println" can be considered a Function. In the given class I also try to assign "System.out::println" to a variable of type Function<String, Void> (which is the closest applicable type I can imagine), but this gives an error as expected. So I don't see why there's an ambiguity, and if I understand the specification [1] correctly, there actually isn't.

      [1] https://docs.oracle.com/javase/specs/jls/se11/html/jls-15.html#jls-15.12.2.1

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile the given class

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The class gives 1 error:

      Wrapper.java:18: error: incompatible types: bad return type in method reference
              Function<String, Void> f = System.out::println;
                                         ^
          void cannot be converted to Void

      ACTUAL -
      The class gives 3 errors. Besides the expected error, it also gives the following 2:

      Wrapper.java:15: error: reference to pipe is ambiguous
              new Wrapper<>("hello world").pipe(System.out::println);
                                          ^
        both method <R>pipe(Function<? super T,? extends R>) in Wrapper and method pipe(Consumer<? super T>) in Wrapper match
        where R,T are type-variables:
          R extends Object declared in method <R>pipe(Function<? super T,? extends R>)
          T extends Object declared in class Wrapper
      Wrapper.java:15: error: incompatible types: cannot infer type-variable(s) R
              new Wrapper<>("hello world").pipe(System.out::println);
                                               ^
          (argument mismatch; bad return type in method reference
            void cannot be converted to R)
        where R,T are type-variables:
          R extends Object declared in method <R>pipe(Function<? super T,? extends R>)
          T extends Object declared in class Wrapper


      ---------- BEGIN SOURCE ----------
      import java.util.function.Consumer;
      import java.util.function.Function;

      public class Wrapper<T> {

          private final T t;

          public Wrapper(T t) { this.t = t; }

          public <R> R pipe(Function<? super T, ? extends R> f) { return f.apply(t); }

          public void pipe(Consumer<? super T> c) { c.accept(t); }

          public static void main(String... args) {
              new Wrapper<>("hello world").pipe(System.out::println);

              Consumer<String> c = System.out::println;
              Function<String, Void> f = System.out::println;
          }

      }

      ---------- END SOURCE ----------

            vromero Vicente Arturo Romero Zaldivar
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: