Method invocation applicability rules confusion

Chris Dennis chris.w.dennis at gmail.com
Fri Dec 8 17:34:06 UTC 2017


Hi All,

I’ve hit an interesting issue with an API that I am responsible for whereby the equivalent to the following does not compile:

public class TargetTypingWeirdness {

  public static void test() {
    Consumer<String> stringConsumer = System.out::println;

    f(stringConsumer, o -> o.toString());
  }

  static <T> Runnable f(Consumer<T> c, T t) {
    return () -> c.accept(t);
  }

  static <T> Consumer<Object> f(Consumer<T> c, Function<Object, T> ft) {
    return o -> c.accept(ft.apply(o));
  }
}

with:

TargetTypingWeirdness.java:9: error: reference to f is ambiguous
    f(stringConsumer, o -> o.toString());
    ^
  both method <T#1>f(Consumer<T#1>,T#1) in TargetTypingWeirdness and method <T#2>f(Consumer<T#2>,Function<Object,T#2>) in TargetTypingWeirdness match
  where T#1,T#2 are type-variables:
    T#1 extends Object declared in method <T#1>f(Consumer<T#1>,T#1)
    T#2 extends Object declared in method <T#2>f(Consumer<T#2>,Function<Object,T#2>)
TargetTypingWeirdness.java:9: error: incompatible types: cannot infer type-variable(s) T
    f(stringConsumer, o -> o.toString());
     ^
    (argument mismatch; String is not a functional interface)
  where T is a type-variable:
    T extends Object declared in method <T>f(Consumer<T>,T)
2 errors

I’m trying to figure out if this is an allowed behavior under the spec, or a bug in javac?

Any help greatly appreciated,

Chris


More information about the compiler-dev mailing list