Java 8 Consumer / Function Lambda Ambiguity

Tengo un método sobrecargado que toma un objeto Consumer y Function respectivamente y devuelve un tipo genérico que coincide con el Consumer / Function correspondiente. Pensé que esto estaría bien, pero cuando trato de llamar a cualquier método con una expresión lambda, aparece un error que indica que la referencia al método es ambigua.

Basado en mi lectura deJLS §15.12.2.1. Identificar los métodos potencialmente aplicables: parece que el compilador debería saber que mi lambda con un bloque vacío coincide con el método Consumer y mi lambda con un tipo de retorno coincide con el método Function.

Puse el siguiente código de muestra que no se compila:

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);
    }
  }
}

También encontré unsimilar stackoverflow post que resultó ser un error del compilador. Mi caso es muy similar, aunque un poco más complicado. Para mí, esto todavía parece un error, pero quería asegurarme de que no estoy malinterpretando la especificación del idioma para lambdas. Estoy usando Java 8u45 que debería tener todas las últimas correcciones.

Si cambio mis llamadas de método para que se envuelvan en un bloque, todo parece compilarse, pero esto agrega verbosidad adicional y muchos formateadores automáticos lo formatearán en varias líneas.

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

Respuestas a la pregunta(1)

Su respuesta a la pregunta