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

STC sometimes requires explicit closure to SAM cast inside of another closure




      After upgrading to the 3.0.8 version, I observed several improvements in STC, but it looks like some cases are still uncovered. Say I have the following script (tested with Groovy console):

      import groovy.transform.CompileStatic
      import java.util.function.Predicate
      import java.util.function.Supplier
      import java.util.stream.Collectors
      class Test {
        void testMe() {
          String maybeSomeString = Optional.of("Some Name")
              .orElseThrow({ new NoSuchElementException("Nothing found") }) // line 1 - no explicit cast
          println maybeSomeString
          List stringList = ["1ab", "2cd"]
              .flatMap({ it.toList().stream() })
              .filter({ Character.isLetterOrDigit(it.chars[0]) }) // line 2 - no explicit cast
          println stringList
          [1, 2, 3]
                String maybeSomeOtherString = Optional
                    .of("Some Other Name")
                    .orElseThrow({ new NoSuchElementException("Nothing found") } as Supplier) // line 3 - explicit cast needed
                return "$it: $maybeSomeOtherString".toString()
                List list = it.toList()
                    .filter({ Character.isLetterOrDigit(it.chars[0]) }) // line 4 - no explicit cast and no explicit parameter type
                println list
              .forEach({println it })
      new Test().testMe()

      In line 3, an explicit cast to Supplier is needed. It wasn't required for 3.0.7. When removed, the checker throws

      [Static type checking] - Cannot call <X extends java.lang.Throwable> java.util.Optional <java.lang.String>#orElseThrow(java.util.function.Supplier <? extends X>) with arguments [groovy.lang.Closure <java.util.NoSuchElementException>] 
       at line: 26, column: 41

      As can be seen from the sample, coercion works if the closure is not nested inside of another closure.

      For comparison, with the 3.0.7 version, line 1 and 2 behaves the same as for 3.0.8.
      In 3.0.7, line 3 did not require an explicit cast. In line 4, 3.0.7 requires explicit cast and explicit parameter declaration, while 3.0.8 does not require either.





            • Assignee:
              emilles Eric Milles
              dmurat Damir Murat
            • Votes:
              0 Vote for this issue
              2 Start watching this issue


              • Created: