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

Compiles fine but when calling method, compiler reports incompatible types

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P4 P4
    • None
    • 17.0.10
    • tools
    • generic
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      Debian stable, Linux

      A DESCRIPTION OF THE PROBLEM :
      I have a method in file “MyImpl” with header “MyImpl andConsume(TConsumer<?> consumer)”, which compiles fine (MyImpl actually extends “MyInterface<Random>”; I skip the details here).

      But when using it using an instance of “TConsumer<?> consumer” and assigning the result to a variable declared as type “MyImpl”, the compiler reports “error: incompatible types: MyInterface<Random> cannot be converted to MyImpl”.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      git clone https://github.com/oliviercailloux/JARiS.git
      git checkout simplified
      javac -d "out/" somebug/*.java
      javac -classpath "out/" "someuser/UserClass.java"

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Either javac should refuse to compile the first method, or it should allow to use it as its header declares.
      ACTUAL -
      javac compiles the files in the “somebug” package fine, thus, seems happy with the method that declares that it returns “MyImpl”; but then it refuses to compile the file in “someuser” which calls the method and expects it to return an instance of “MyImpl”.

      ---------- BEGIN SOURCE ----------
      package somebug;

      import java.util.Random;

      public interface MyImpl extends MyInterface<Random> {
        public static MyImpl instance() {
          return new MyImpl() {
            @Override
            public MyImpl andConsume(TConsumer<?> consumer) {
              return this;
            }
          };
        }

        @Override
        public MyImpl andConsume(TConsumer<? extends Random> consumer);
      }

      package somebug;

      import java.util.Random;

      public interface MyImpl extends MyInterface<Random> {
        public static MyImpl instance() {
          return new MyImpl() {
            @Override
            public MyImpl andConsume(TConsumer<?> consumer) {
              return this;
            }
          };
        }

        @Override
        public MyImpl andConsume(TConsumer<? extends Random> consumer);
      }

      package somebug;

      import java.util.Random;

      public interface TConsumer<X extends Random> {
        public void consuming(Integer t);
      }

      ---
      To be compiled afterwards (separately).
      ---
      package someuser;

      import somebug.MyImpl;
      import somebug.TConsumer;

      public class UserClass {
      public void gradeCode() {
      MyImpl tryTarget = MyImpl.instance();
      TConsumer<?> consumer = i -> {};
      MyImpl got = tryTarget.andConsume(consumer);
      }
      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      In MyImpl.java, change “andConsume(TConsumer<?> consumer);” to “andConsume(TConsumer<? extends Random> consumer);”

      As implemented in https://github.com/oliviercailloux/JARiS/compare/simplified...solved

      FREQUENCY : always


            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: