Ambiguidade do Lambda de consumidor / função do Java 8

Eu tenho um método sobrecarregado que leva um consumidor e um objeto de função, respectivamente, e retorna um tipo genérico que corresponde ao consumidor / função correspondente. Eu pensei que isso seria bom, mas quando tento chamar qualquer método com uma expressão lambda, recebo um erro indicando que a referência ao método é ambígua.

Com base na minha leitura deJLS §15.12.2.1. Identifique métodos potencialmente aplicáveis: parece que o compilador deve saber que meu lambda com um bloco vazio corresponde ao método Consumer e meu lambda com um tipo de retorno corresponde ao método Function.

Eu montei o seguinte código de exemplo que falha ao compilar:

import java.util.function.Consumer;
import java.util.function.Function;

public class AmbiguityBug {
  public static void main(String[] args) {
    doStuff(getPattern(x -> System.out.println(x)));
    doStuff(getPattern(x -> String.valueOf(x)));
  }

  static Pattern<String, String> getPattern(Function<String, String> function) {
    return new Pattern<>(function);
  }

  static ConsumablePattern<String> getPattern(Consumer<String> consumer) {
    return new ConsumablePattern<>(consumer);
  }

  static void doStuff(Pattern<String, String> pattern) {
    String result = pattern.apply("Hello World");
    System.out.println(result);
  }

  static void doStuff(ConsumablePattern<String> consumablePattern) {
    consumablePattern.consume("Hello World");
  }

  public static class Pattern<T, R> {
    private final Function<T, R> function;

    public Pattern(Function<T, R> function) {
      this.function = function;
    }

    public R apply(T value) {
      return function.apply(value);
    }
  }

  public static class ConsumablePattern<T> {
    private final Consumer<T> consumer;

    public ConsumablePattern(Consumer<T> consumer) {
      this.consumer = consumer;
    }

    public void consume(T value) {
      consumer.accept(value);
    }
  }
}

Eu também encontrei umsemelhante pós stackoverflow que acabou por ser um bug do compilador. Meu caso é muito parecido, embora um pouco mais complicado. Para mim, isso ainda parece um bug, mas eu queria ter certeza de que não estou entendendo mal a especificação de idioma para lambdas. Estou usando o Java 8u45, que deve ter todas as correções mais recentes.

Se eu alterar minhas chamadas de método para serem agrupadas em um bloco, tudo parece compilar, mas isso adiciona mais verbosidade e muitos formatadores automáticos a reformatam em várias linhas.

doStuff(getPattern(x -> { System.out.println(x); }));
doStuff(getPattern(x -> { return String.valueOf(x); }));

questionAnswers(1)

yourAnswerToTheQuestion