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

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

    XMLWordPrintableJSON

    Details

      Description

      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
      
      @CompileStatic
      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"]
              .stream()
              .flatMap({ it.toList().stream() })
              .filter({ Character.isLetterOrDigit(it.chars[0]) }) // line 2 - no explicit cast
              .collect(Collectors.toList())
          
          println stringList
      
          [1, 2, 3]
              .stream()
              .map({
                String maybeSomeOtherString = Optional
                    .of("Some Other Name")
                    .orElseThrow({ new NoSuchElementException("Nothing found") } as Supplier) // line 3 - explicit cast needed
      
                return "$it: $maybeSomeOtherString".toString()
              })
              .peek({
                List list = it.toList()
                    .stream()
                    .filter({ Character.isLetterOrDigit(it.chars[0]) }) // line 4 - no explicit cast and no explicit parameter type
                    .collect(Collectors.toList())
      
                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.

      Tnx

        Attachments

          Activity

            People

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

              Dates

              • Created:
                Updated:
                Resolved: