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

Inferred generic type differs depending on presence of unrelated type arguments

    XMLWordPrintable

Details

    • generic
    • generic

    Description

      ADDITIONAL SYSTEM INFORMATION :
      Windows 10 Pro
      javac 1.8.0_402
      javac 9.0.4
      javac 21.0.2
      javac 23-ea+8

      A DESCRIPTION OF THE PROBLEM :
      The presence or absence of an unrelated generic type on a method compiles to different inferred generic types for vararg arguments in lambdas passed to the outer method (see example code).
      The inferrence gave the expected output on code compiled with Adoptium 8, IBM Semeru 17, and ECJ 3.36 while it results in the upper bound on Adoptium 9-23 and version 21 of IBM Semeru, Red Hat, Zulu, and Microsoft.
      Execution runtime does not matter. Code compiled with Adoptium 8 run in Adoptium 23 will give expected output while code compiled in Adoptium 17 run in IBM Semeru 17 will result in the unexpected output.

      REGRESSION : Last worked in version 8u401

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Create a lambda calling a generic method m1 with generic varargs and pass it to another method m2. Depending if m2 is generic itself the inferred type of the varargs differ.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Since the generic type parameter T is unrelated to the rest of the code I would expected to both calls behave the same and the vararg type parameter X to be inferred as java.lang.Integer.

      The output of the code should be
      class java.lang.Integer
      class java.lang.Integer
      ACTUAL -
      The output of the code is
      class java.lang.Integer
      class java.lang.Object

      ---------- BEGIN SOURCE ----------
      public class Generic {

          public static void main(String... args) {
              run(() -> supplyNull(Integer.valueOf(1)));
              runT(() -> supplyNull(Integer.valueOf(1)));
          }

          static <R, X> R supplyNull(X... varargs) {
              System.out.println(varargs.getClass().getComponentType());
              return null;
          }

          // behaviour differs when <T> is present
          static void run(Runnable runnable) { runnable.run(); }
          static <T> void runT(Runnable runnable) { runnable.run(); }
      }
      ---------- END SOURCE ----------

      FREQUENCY : always


      Attachments

        Activity

          People

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

            Dates

              Created:
              Updated: