I have 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. Yet the compiler still claims that the call is ambiguous. How is that possible?
import java.util.function.Supplier;
public class GenericLambdas {
    public static void main(String[] args) {
        wrap(System.out::println);   // Compiler error here
        wrap(() -> {});              // No error
        wrap(System.out::flush);     // No error
    }
    static <R> void wrap(Supplier<R> function) {}
    static void wrap(Runnable function) {}
}
Compiler output:
Error:Error:line (5)java: reference to wrap is ambiguous
    both method <R>wrap(java.util.function.Supplier<R>) in GenericLambdas and method wrap(java.lang.Runnable) in GenericLambdas match 
Error:Error:line (5)java: incompatible types: cannot infer type-variable(s) R
    (argument mismatch; bad return type in method reference
      void cannot be converted to R)
Based on the second error (argument mismatch, void cannot be converted to R), shouldn't the compiler be able to disambiguate the call? That would then take care of both compiler errors (as it will neither be ambiguous, nor will it try to convert void to R).
And why are () -> {} and System.out::flush able to resolve? They have the same signature as System.out.println. Granted that System.out.println is overloaded with versions that take an argument, but none of those overloaded versions match either Supplier or Runnable, so I don't see how they would be relevant here.
EDIT:
It seems that this does compile and run with the Eclipse compiler. Which compiler is correct, or is either behavior allowed?
 
     
     
    