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

Diamond inheritance of interfaces makes method return type incompatible

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 2.3.10, 2.4.3
    • Fix Version/s: 2.4.4
    • Component/s: Compiler
    • Labels:
      None

      Description

      While working on Gradle, I bumped into a failure with the Groovy compiler that works fine in Java.

      Example code that fails with both Groovy compiler 2.3.10 and 2.4.3:

      Groovy
      interface Item {}
      interface DerivedItem extends Item {}
      
      interface Base {
        Item getItem()
      }
      class BaseImpl implements Base {
        Item getItem() { null }
      }
      
      interface First extends Base {
        DerivedItem getItem()
      }
      
      class FirstImpl extends BaseImpl implements First {
        DerivedItem getItem() { null }
      }
      
      interface Second extends First {}
      class SecondImpl extends FirstImpl implements Second {}
      

      The error message is:

      Script1.groovy: 8: The return type of Item getItem() in BaseImpl is incompatible with DerivedItem in First. At [8:3]  @ line 8, column 3.
           Item getItem() { null }
           ^
      

      However, changing the implementation of SecondImpl like this fixes the compile error:

      Fixed Groovy
      class SecondImpl extends FirstImpl implements Second {
        DerivedItem getItem() { super.item }
      }
      

      The equivalent code compiles fine in Java:

      Java
      public class CompileJava {
          interface Item {}
          interface DerivedItem extends Item {}
          
          interface Base {
            Item getItem();
          }
          class BaseImpl implements Base {
            public Item getItem() { return null; }
          }
          
          interface First extends Base {
            DerivedItem getItem();
          }
          
          class FirstImpl extends BaseImpl implements First {
            public DerivedItem getItem() { return null; }
          }
          
          interface Second extends First {}
          class SecondImpl extends FirstImpl implements Second {}
      }
      

        Attachments

          Activity

            People

            • Assignee:
              blackdrag Jochen Theodorou
              Reporter:
              lptr Lóránt Pintér
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: