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

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

            Dates

              Created:
              Updated:
              Resolved: