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

switch expressions lack support for deferred type-checking

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 17
    • 16, 17
    • tools
    • None
    • b24

      This test:

      import java.util.function.*;

      class Test {
          <Z> void m(Consumer<Z> c, Class<Z> cl) {

          }

          void test(boolean b, int i) {
              m(s -> s.length(), String.class);
              m(b ? s -> s.length() : s -> s.length(), String.class);
              m(switch (i) {
                  case 0 -> s -> s.length();
                  default -> s -> s.length();
              }, String.class);
          }
      }


      Fails to compile:

      Test.java:12: error: cannot find symbol
                  case 0 -> s -> s.length();
                                  ^
        symbol: method length()
        location: variable s of type Z
        where Z is a type-variable:
          Z extends Object declared in method <Z>m(Consumer<Z>,Class<Z>)
      Test.java:13: error: cannot find symbol
                  default -> s -> s.length();
                                   ^
        symbol: method length()
        location: variable s of type Z
        where Z is a type-variable:
          Z extends Object declared in method <Z>m(Consumer<Z>,Class<Z>)
      Test.java:11: error: incompatible types: inference variable Z has incompatible equality constraints String,Z
              m(switch (i) {
               ^
        where Z is a type-variable:
          Z extends Object declared in method <Z>m(Consumer<Z>,Class<Z>)
      3 errors


      Note that the first call and the second compile without issues.

      The problem is caused by the fact that DeferredAttr.PolyScanner does not look inside switch expression nodes. As a result, DeferredAttr.OverloadStuckPolicy and DefrredAttr.CheckStuckPolicy do not collect "stuck" type variables from functional interface targets required inside the arms of a switch expression (unlike what happens e.g. for conditionals). Because of that, Consumer<Z> is not detected as a non-concrete type; as such the compiler just tries to use it as a target, which generates the spurious errors seen above.

            jlahoda Jan Lahoda
            mcimadamore Maurizio Cimadamore
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: