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

Type inference fails for lambda/method reference using overloaded method

XMLWordPrintable

    • generic
    • generic

      FULL PRODUCT VERSION :
      java version "9"
      Java(TM) SE Runtime Environment (build 9+181)
      Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.1.7601]

      A DESCRIPTION OF THE PROBLEM :
      Compilation of attached source code fails with javac 9, but not with javac 1.8.0_144.

      The problem appears both when using method references and when using lamdas with typeless arguments. It does not appear when using typeful arguments in one of the lambdas.

      It seems to be related to method overloading, since using a non-overloaded method (in the inner typeless lambda) does compile.

      This bug might be related to JDK-8164611, with the difference that my example actually does compile with javac 1.8.

      REGRESSION. Last worked in version 8u144

      ADDITIONAL REGRESSION INFORMATION:
      java version "1.8.0_144"
      Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
      Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile attached source code using javac 9

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Compilation success
      ACTUAL -
      Compilation failed

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      C:\Users\RoyB\java>javac javacbug\OptionalMapN.java
      javacbug\OptionalMapN.java:19: error: incompatible types: cannot infer type-variable(s) T#1,U#1,R#1,T#1,U#1,R#1
              return map2(Function::apply, map2(f::apply, tOpt, uOpt), vOpt);
                         ^
          (argument mismatch; invalid method reference
            method apply in interface Function<T#3,R#3> cannot be applied to given types
              required: Object
              found: Object,V
              reason: actual and formal argument lists differ in length)
        where T#1,U#1,R#1,V,T#2,U#2,R#2,T#3,R#3 are type-variables:
          T#1 extends Object declared in method <T#1,U#1,R#1>map2(BiFunction<T#1,U#1,R#1>,Optional<T#1>,Optional<U#1>)
          U#1 extends Object declared in method <T#1,U#1,R#1>map2(BiFunction<T#1,U#1,R#1>,Optional<T#1>,Optional<U#1>)
          R#1 extends Object declared in method <T#1,U#1,R#1>map2(BiFunction<T#1,U#1,R#1>,Optional<T#1>,Optional<U#1>)
          V extends Object declared in method <T#2,U#2,V,R#2>map3_doesNotCompileWithJavac9(TriFunction<T#2,U#2,V,R#2>,Optional<T#2>,Optional<U#2>,Optional<V>)
          T#2 extends Object declared in method <T#2,U#2,V,R#2>map3_doesNotCompileWithJavac9(TriFunction<T#2,U#2,V,R#2>,Optional<T#2>,Optional<U#2>,Optional<V>)
          U#2 extends Object declared in method <T#2,U#2,V,R#2>map3_doesNotCompileWithJavac9(TriFunction<T#2,U#2,V,R#2>,Optional<T#2>,Optional<U#2>,Optional<V>)
          R#2 extends Object declared in method <T#2,U#2,V,R#2>map3_doesNotCompileWithJavac9(TriFunction<T#2,U#2,V,R#2>,Optional<T#2>,Optional<U#2>,Optional<V>)
          T#3 extends Object declared in interface Function
          R#3 extends Object declared in interface Function
      javacbug\OptionalMapN.java:28: error: cannot find symbol
              return map2((vrFunc, v) -> vrFunc.apply(v), map2((t, u) -> f.apply(t, u), tOpt, uOpt), vOpt);
                                               ^
        symbol: method apply(V)
        location: variable vrFunc of type Object
        where V,T,U,R are type-variables:
          V extends Object declared in method <T,U,V,R>map3_alsoDoesNotCompileWithJavac9(TriFunction<T,U,V,R>,Optional<T>,Optional<U>,Optional<V>)
          T extends Object declared in method <T,U,V,R>map3_alsoDoesNotCompileWithJavac9(TriFunction<T,U,V,R>,Optional<T>,Optional<U>,Optional<V>)
          U extends Object declared in method <T,U,V,R>map3_alsoDoesNotCompileWithJavac9(TriFunction<T,U,V,R>,Optional<T>,Optional<U>,Optional<V>)
          R extends Object declared in method <T,U,V,R>map3_alsoDoesNotCompileWithJavac9(TriFunction<T,U,V,R>,Optional<T>,Optional<U>,Optional<V>)
      2 errors

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      package javacbug;

      import java.util.Optional;
      import java.util.function.BiFunction;
      import java.util.function.Function;

      public final class OptionalMapN {

          public static <T, U, R> Optional<R> map2(BiFunction<T, U, R> f, Optional<T> tOpt, Optional<U> uOpt) {
              return tOpt.flatMap(t -> uOpt.map(u -> f.apply(t, u)));
          }

          public static <T, U, V, R> Optional<R> map3_doesNotCompileWithJavac9(
                  TriFunction<T, U, V, R> f,
                  Optional<T> tOpt,
                  Optional<U> uOpt,
                  Optional<V> vOpt) {

              return map2(Function::apply, map2(f::apply, tOpt, uOpt), vOpt);
          }

          public static <T, U, V, R> Optional<R> map3_alsoDoesNotCompileWithJavac9(
                  TriFunction<T, U, V, R> f,
                  Optional<T> tOpt,
                  Optional<U> uOpt,
                  Optional<V> vOpt) {

              return map2((vrFunc, v) -> vrFunc.apply(v), map2((t, u) -> f.apply(t, u), tOpt, uOpt), vOpt);
          }

          public static <T, U, V, R> Optional<R> map3_compilesWithBothJavac8_144andJavac9(
                  TriFunction<T, U, V, R> f,
                  Optional<T> tOpt,
                  Optional<U> uOpt,
                  Optional<V> vOpt) {

              Optional<R> rOpt1 = map2((Function<V,R> vrFunction, V v) -> vrFunction.apply(v), map2(f::apply, tOpt, uOpt), vOpt);
              Optional<R> rOpt2 = map2(Function::apply, map2((T t, U u) -> f.apply(t, u), tOpt, uOpt), vOpt);
              Optional<R> rOpt3 = map2(Function::apply, map2(f::partialApply, tOpt, uOpt), vOpt);
              return rOpt3;
          }

          private OptionalMapN() {
          }

          @FunctionalInterface
          public static interface TriFunction<T, U, V, R> {

              public R apply(T t, U u, V v);

              public default Function<V, R> apply(T t, U u) {
                  return v -> apply(t, u, v);
              }

              public default Function<V,R> partialApply(T t, U u) {
                  return v -> apply(t, u, v);
              }

          }

      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      See attached source code. Basically any nudge providing more type info works.

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: