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

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

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 3.0.7
    • Fix Version/s: 3.0.8, 4.0.0-alpha-3
    • Component/s: Compiler
    • Labels:
      None
    • Environment:
      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

          Activity

            People

            • Assignee:
              emilles Eric Milles
              Reporter:
              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