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

@TypeChecked Error: Members of Iterable<T extends Foo> are Foo, not Object

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 3.0.7
    • 3.0.8, 4.0.0-alpha-3, 2.5.17
    • Compiler
    • None
    • Windows 10
      jdk-11.0.10.9-hotspot
      IntelliJ 2020.3.2

    Description

      Problem
      Trying to build the sample test code below fails with:

      Groovyc: [Static type checking] - No such property: name for class: java.lang.Object
      Groovyc: Expected parameter of type java.lang.Object but got simple.groovy.bugs.groovy3.gb_2021_03_05.iterable_t_extends.Foo
      Groovyc: [Static type checking] - No such property: name for class: java.lang.Object
      

      If we do not explicitly give the member type of the IterableTExtendsFoo iterable, Groovy assumes that the type is Object, even though it has been defined as being a subclass of Foo in the definition of IterableTExtendsFoo<T extends Foo>.

      Expected

      • Code should compile.
      • If Groovy could not deduce that IterableTExtendsFoo has been initialized with a List<T extends Foo>, then it should reject the line where the IterableTExtendsFoo ctor is called.
      • Note: Works as expected in Groovy 2.5.x (at least up to 2.5.14)

      Sample Code

      import groovy.transform.TypeChecked
      import org.junit.Ignore
      import org.junit.Test
      
      @TypeChecked
      class Groovy3_Iterable_T_extends_Bug {
      	@Test
      	@Ignore
      	void 'Groovy 3-0-7 Members of Iterable T extends Foo are Foo'() {
      		// Compiler should reject the following line if the ctor arg would not of type List<T extends Foo>
      		final iterableTExtendsFoo = new IterableTExtendsFoo([new Foo('Sli'),new Foo('Msha'),new Foo('Dy'),])
      		//final iterableTExtendsFoo = new IterableTExtendsFoo<Foo>([new Foo('Sli'),new Foo('Msha'),new Foo('Dy'),]) // Explicitly giving the iterable member type makes the code compile
      		println iterableTExtendsFoo.collect { "Hi, my name is: $it.name" }
      		println iterableTExtendsFoo.collect { Foo f -> "name=$f.name" }
      	}
      }
      
      @Canonical class Foo { String name }
      
      @Canonical
      class IterableTExtendsFoo<T extends Foo> implements Iterable<T> {
      	List<T> foos
      	@Override Iterator<T> iterator() { foos.iterator() }
      }
      

      Attachments

        Issue Links

          Activity

            People

              emilles Eric Milles
              emge mgroovy
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0h
                  0h
                  Logged:
                  Time Spent - 40m
                  40m