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

Compiler fails to perform type-inference for a lambda passed to a generic method

    XMLWordPrintable

    Details

    • Subcomponent:
    • CPU:
      x86_64
    • OS:
      windows_7

      Description

      FULL PRODUCT VERSION :
      java version "1.8.0-ea"
      Java(TM) SE Runtime Environment (build 1.8.0-ea-b121)
      Java HotSpot(TM) 64-Bit Server VM (build 25.0-b63, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.1.7601]

      A DESCRIPTION OF THE PROBLEM :
      When a lambda function is wrapped inside a generic method and such method is being passed as an argument of another method, compiler fails to resolve type of the lambda function.

      Surprisingly, it's able to resolve when generics are declared for a class (e.g. MyClass<A>), but fails when generics are declared for a method (e.g. <A> void foo(...)).

      See the attached code example.


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      public class LambdaAndGenerics {
          public static interface Predicate<T> {
              boolean test(T t);
          }
          public static <I, T extends I> I lambdaWrapper(final T lambda) {
              return lambda;
          }
          public static void main(String[] args) {
              new DoesNotFail<String, Integer>().start();
              new Fails().start();
          }

          /**
           * Works fine for N, M declared for a class
           */
          static class DoesNotFail<M, N> {
              void start() {
                  System.out.println(one(lambdaWrapper(e -> false))); // compiler works-out types correctly
              }
              String one(Class<N> arg) {
                  return "DoesNotFail class: " + arg;
              }
              String one(Predicate<M> arg) {
                  return "DoesNotFail predicate: " + arg.test(null);
              }
          }

          /**
           * Fails when N, M are declared for methods
           */
          static class Fails {
              void start() {
                  System.out.println(one(lambdaWrapper(e -> false))); // COMPILER ERRORS "reference to one is ambiguous" + "cannot infer type variables"
                  // one(null); // COMPILER ERROR "reference to one is ambiguous" which is correct
              }
              <N> String one(Class<N> arg) {
                  return "Fails class: " + arg;
              }
              <M> String one(Predicate<M> arg) {
                  return "Fails predicate: " + arg.test(null);
              }
          }
      }

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

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              vromero Vicente Arturo Romero Zaldivar
              Reporter:
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: