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

Regression in method type argument inference

XMLWordPrintable

    • x86
    • windows_xp

      FULL PRODUCT VERSION :
      java version "1.7.0-ea"
      Java(TM) SE Runtime Environment (build 1.7.0-ea-b09)
      Java HotSpot(TM) Client VM (build 1.7.0-ea-b09, mixed mode, sharing)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows XP [version 5.1.2600]

      A DESCRIPTION OF THE PROBLEM :
      My parser generator doesn't compile with recent jdk snapshot (jdk7)
      due to an error in the way javac infers a method.

      I've tried to isolate the problem but because i'am busy these days
      i've just copy/paste the types and remove the implementation details,
      sorry. I will try to post a better test case later.

      This is a regression because the test case compiles with jdk1.6.0
      (and eclipse) but there is no way currently to report a bug againt jdk1.7
      using the web page. So i have set the regression field to jdk6 beta 2.

      The fact that a return type is involved is important, it seems javac
      used it even if it should not in that case.

      REGRESSION. Last worked in version mustang

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Try to compile the code.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      It compiles
      ACTUAL -
      it doesn't compile

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      C:\java\workspace\java-patch\src>javac JavacInferenceBug.java
      JavacInferenceBug.java:42: incompatible types found : JavacInferenceBug.LexerLocationBuilder<JavacInferenceBug.LocationToken
      BufferFilter<B,java.lang.Object>>
      required: JavacInferenceBug.LexerLocationBuilder<JavacInferenceBug.LocationToken
      BufferFilter<B,D>>
            return createLocationBuilder(wrapTokenBuffer(buffer));
                                        ^
      1 error

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------

      public class JavacInferenceBug {
          
          interface LexerBuffer {
          }
          
          interface TokenBuffer<D> {
              
          }
          
          interface LocationBuffer extends LexerBuffer {
              
          }
          
          static class LocationBufferFilter<B extends LexerBuffer> implements LocationBuffer {
              
          }
          
          static class LocationTokenBufferFilter<B extends TokenBuffer<D> & LexerBuffer,D> extends LocationBufferFilter<B> implements TokenBuffer<D> {
              
          }
          
          static class LexerBuilder<B> {
              
          }
          
          static class LexerLocationBuilder<B extends LocationBuffer> extends LexerBuilder<B> {
              
          }
          
          public static <D,B extends TokenBuffer<D> & LexerBuffer>
          LocationTokenBufferFilter<B,D> wrapTokenBuffer(B buffer) {
            return null;
          }
          
          
          public static <B extends LocationBuffer> LexerLocationBuilder<B> createLocationBuilder(B buffer) {
              return null;
          }

          public static <B extends TokenBuffer<D> & LexerBuffer,D> LexerLocationBuilder<LocationTokenBufferFilter<B,D>> createLocationBuilderAndWrapTokenBuffer(B buffer) {
            return createLocationBuilder(wrapTokenBuffer(buffer));
          }
      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      don't let the compiler infers type argument and write them explicitely.
      After doing a little alpha renaming and wrapping, the example becomes more
      readable:

      ==> T6536404.java <==
      interface LexerBuffer {
      }

      interface TokenBuffer<D> {
      }

      interface LocationBuffer extends LexerBuffer {
      }

      class LocationBufferFilter<B extends LexerBuffer>
          implements LocationBuffer {
      }

      class LocationTokenBufferFilter<B extends TokenBuffer<D> & LexerBuffer,D>
          extends LocationBufferFilter<B>
          implements TokenBuffer<D> {
      }

      class LexerBuilder<B> {}

      class LexerLocationBuilder<B extends LocationBuffer>
          extends LexerBuilder<B> {
      }

      abstract class JavacInferenceBug {

          abstract <D1,B1 extends TokenBuffer<D1> & LexerBuffer>
              LocationTokenBufferFilter<B1,D1> wrapTokenBuffer(B1 buffer);

          abstract <B2 extends LocationBuffer>
              LexerLocationBuilder<B2> createLocationBuilder(B2 buffer);

          <B3 extends TokenBuffer<D3> & LexerBuffer,D3>
          void createLocationBuilderAndWrapTokenBuffer(B3 buffer) {
              LexerLocationBuilder<LocationTokenBufferFilter<B3,D3>> x;
              x = createLocationBuilder(wrapTokenBuffer(buffer));
          }
      }

      This file is attached to the bug.

      The compiler error is:

      T6536404.java:36: incompatible types
      found : LexerLocationBuilder<LocationTokenBufferFilter<B3,java.lang.Object>>
      required: LexerLocationBuilder<LocationTokenBufferFilter<B3,D3>>
              x = createLocationBuilder(wrapTokenBuffer(buffer));
                                       ^
      1 error

            ahe Peter Ahe
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: