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

Anomaly in type inference when lamba expression is argument to a generic method

    XMLWordPrintable

Details

    • generic
    • generic

    Description

      ADDITIONAL SYSTEM INFORMATION :
      Fedora Linux Release 38

      A DESCRIPTION OF THE PROBLEM :
      Code of the form m1(m2(lamba)) can sometimes give a compile-time error, even though the type returned by m2 matches the parameter type of m1. This can occur when m2 is a generic method, but seems to depend on how many type parameters m2 has.
      The attached simplified test program shows that the compiler may or may not reject,
          System.out.println(method(withLambda));
      although it accepts the use of a temporary variable,
          var x = method(withLambda);
          System.out.println(x);
      The compiler correctly determines that,
          two("ab", s -> s + "cd")
      returns a String. The error messages confirm it. And if the result is cast to a String, the compiler warns the cast is redundant. Yet without the cast it complains that println(String) is ambiguous.
      This is also reproduceable with types other than String. The problem is always with,
          <T,R> R two(T t, Function<T,R> fn)
      whereas
          <R> R one(Supplier<R> fn)
      always works.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Attempt to compile the attached code.
      It will fail at the line
          System.out.println(two("ab", s -> s + "cd"));
      Remove that line and the remaining code will compile and give correct results at runtime.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The code
          System.out.println(two("ab", s -> s + "cd"))
      should compile and work the same as
          var x2 = two("ab", s -> s + "cd");
          System.out.println(x2);
      ACTUAL -
      MaybeBug.java:25: error: reference to println is ambiguous
              System.out.println(two("ab", s -> s + "cd"));
                        ^
        both method println(char[]) in PrintStream and method println(String) in PrintStream match
      MaybeBug.java:25: error: method println in class PrintStream cannot be applied to given types;
              System.out.println(two("ab", s -> s + "cd"));
                                ^
        required: char[]
        found: String
        reason: argument mismatch; inference variable R has incompatible bounds
            upper bounds: char[],Object
            lower bounds: String
        where R,T are type-variables:
          R extends Object declared in method <T,R>two(T,Function<T,R>)
          T extends Object declared in method <T,R>two(T,Function<T,R>)
      2 errors

      ---------- BEGIN SOURCE ----------
      import java.util.function.*;

      public class MaybeBug {
          static <R> R one(Supplier<R> fn) {
              return fn.get();
          }
          
          static <T,R> R two(T t, Function<T,R> fn) {
              return fn.apply(t);
          }
          
          public static void main (String[] args) {
              //this prints "abcd" as expected...
              var x1 = one(() -> "abcd");
              System.out.println(x1);
              
              //so does this...
              System.out.println(one(() -> "abcd"));
              
              //and so does this...
              var x2 = two("ab", s -> s + "cd");
              System.out.println(x2);
              
              //BUT THIS DOESN'T COMPILE...
              System.out.println(two("ab", s -> s + "cd"));
              
              //although this does compile, albeit with a redundant cast warning...
              System.out.println((String)two("ab", s -> s + "cd"));

              //and so does this...
              System.out.println(MaybeBug.<String,String>two("ab", s -> s + "cd"));
          }
      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      Cast the String to a String:
          @SuppressWarnings("cast")
              . . . .
          System.out.println((String)two("ab", s -> s + "cd"));

      FREQUENCY : always


      Attachments

        Activity

          People

            rkale Raghu Kale
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: