Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-8757

Incorrect bytecode produced after compiling class implementing trait with generic method

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Critical
    • Resolution: Fixed
    • Affects Version/s: 2.4.15, 3.0.0-alpha-3, 2.5.2
    • Fix Version/s: 2.4.16, 3.0.0-alpha-4, 2.5.3
    • Component/s: Compiler
    • Labels:
      None

      Description

      T.groovy
      trait T {
          def <T extends Number> T foo(Class<T> c) {
              println c
              return null 
          }
      }
      
      C.groovy
      class C implements T {}
      
      usage.groovy
      new C().foo(Integer)
      
      $ groovyc C.groovy T.groovy
      $ groovy usage.groovy
      class java.lang.Integer
      $ groovyc C.groovy # recompile C using already compiled T
      $ groovy usage.groovy
      Caught: java.lang.VerifyError: Bad return type
      Exception Details:
        Location:
          C.foo(Ljava/lang/Class;)Ljava/lang/Number; @5: areturn
        Reason:
          Type 'java/lang/Object' (current frame, stack[0]) is not assignable to 'java/lang/Number' (from method signature)
        Current Frame:
          bci: @5
          flags: { }
          locals: { 'C', 'java/lang/Class' }
          stack: { 'java/lang/Object' }
        Bytecode:
          0x0000000: 2a2b b600 88b0
      
      java.lang.VerifyError: Bad return type
      Exception Details:
        Location:
          C.foo(Ljava/lang/Class;)Ljava/lang/Number; @5: areturn
        Reason:
          Type 'java/lang/Object' (current frame, stack[0]) is not assignable to 'java/lang/Number' (from method signature)
        Current Frame:
          bci: @5
          flags: { }
          locals: { 'C', 'java/lang/Class' }
          stack: { 'java/lang/Object' }
        Bytecode:
          0x0000000: 2a2b b600 88b0
      
      	at usage.run(usage.groovy:1)
      
      original javap output
      public class C implements T,groovy.lang.GroovyObject {
        public static transient boolean __$stMC;
        public C();
        public <T extends java.lang.Number> T foo(java.lang.Class<T>);
        public <T extends java.lang.Number> T Ttrait$super$foo(java.lang.Class<T>);
        static {};
        protected groovy.lang.MetaClass $getStaticMetaClass();
        public groovy.lang.MetaClass getMetaClass();
        public void setMetaClass(groovy.lang.MetaClass);
        public java.lang.Object invokeMethod(java.lang.String, java.lang.Object);
        public java.lang.Object getProperty(java.lang.String);
        public void setProperty(java.lang.String, java.lang.Object);
      }
      
      recompiled javap output
      public class C implements T,groovy.lang.GroovyObject {
        public static transient boolean __$stMC;
        public C();
        public <T> T foo(java.lang.Class<T>);
        public <T extends java.lang.Number> T Ttrait$super$foo(java.lang.Class<T>);
        static {};
        protected groovy.lang.MetaClass $getStaticMetaClass();
        public groovy.lang.MetaClass getMetaClass();
        public void setMetaClass(groovy.lang.MetaClass);
        public java.lang.Object invokeMethod(java.lang.String, java.lang.Object);
        public java.lang.Object getProperty(java.lang.String);
        public void setProperty(java.lang.String, java.lang.Object);
        public java.lang.Number foo(java.lang.Class);
      }
      

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                paulk Paul King
                Reporter:
                daniilo Daniil Ovchinnikov
              • Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: