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

Diamond inheritance of interfaces makes method return type incompatible

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 2.3.10, 2.4.3
    • 2.4.4
    • Compiler
    • 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

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

            Dates

              Created:
              Updated:
              Resolved: