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

Type checker fails to infer a generic type without an intermediate variable definition

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.2.2
    • Component/s: None
    • Labels:
      None

      Description

      On master, the following code fails:

      import groovy.transform.CompileStatic
      import groovy.transform.Field
      
      class Stream<T> implements Iterable<T> {
          public static Stream<String> from(BufferedReader reader) { new Stream(data:['a','b','c']) }
          
          List<T> data
          
          public Iterator<T> iterator() { data.iterator() }
          
          public <U> Stream<U> flatMap(Closure<? extends Collection<U>> closure) { new Stream(data:data.collect(closure)) }
      }
       
      @CompileStatic
      def test() {
          Map<String,Integer> frequencies = [:].withDefault { 0 }
          BufferedReader r = null
          Stream.from(r)
              .flatMap { String it -> it.toList() }
              .each { String it -> frequencies[it]++ } // to test: .each { frequencies[it]++ }
      }
       
      test()
      

      Curiously, adding an intermediate variable makes this pass:

      import groovy.transform.CompileStatic
      import groovy.transform.Field
      
      class Stream<T> implements Iterable<T> {
          public static Stream<String> from(BufferedReader reader) { new Stream(data:['a','b','c']) }
          
          List<T> data
          
          public Iterator<T> iterator() { data.iterator() }
          
          public <U> Stream<U> flatMap(Closure<? extends Collection<U>> closure) { new Stream(data:data.collect(closure)) }
      }
       
      @CompileStatic
      def test() {
          Map<String,Integer> frequencies = [:].withDefault { 0 }
          BufferedReader r = null
          Stream<String> stream = Stream.from(r)
              .flatMap { String it -> it.toList() }
          stream.each { String it -> frequencies[it]++ } // to test: .each { frequencies[it]++ }
      }
       
      test()
      

        Attachments

          Activity

            People

            • Assignee:
              melix Cédric Champeau
              Reporter:
              melix Cédric Champeau
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: