codeconsole opened a new pull request, #3133:
URL: https://github.com/apache/groovy/pull/3133

   The static type checker rejects a closure or lambda that returns a 
`Closure<R>` value where the expected return type is a functional interface:
   
   ```groovy
   import java.util.function.Supplier
   
   @groovy.transform.CompileStatic
   class C {
       static String take(Supplier<Supplier<String>> s) { s.get().get() }
       static void main(args) {
           Closure<String> c = { 'x' }
           assert take { c } == 'x'   // Cannot return value of type 
groovy.lang.Closure<java.lang.String> for closure expecting 
java.util.function.Supplier<java.lang.String>
           assert take(() -> c) == 'x' // same, "for lambda expecting"
       }
   }
   ```
   
   4.0.33, 5.0.8 and 6.0.0 reject it the same way. The closure branch of 
`StaticTypeCheckingVisitor.checkReturnType` only allowed covariant returns. It 
now also accepts a Closure value when the expected type is a SAM type whose 
method returns void or a supertype of the Closure's type argument (a raw 
Closure is accepted). In that case it records the SAM type as the closure's 
return type. For closures this is enough: the closure method already declares 
the inferred return type, and the returned value gets a Groovy cast, which 
converts the Closure to the interface (as for GROOVY-9971).
   
   A statically compiled lambda's method declared the SAM method's erased 
return type, so the Closure was returned unconverted and the caller failed with 
a ClassCastException. `StaticTypesLambdaWriter` now declares the lambda's 
inferred return type when the SAM method returns a type variable and that 
inferred type is a SAM type, so the same Groovy cast is written at the return.
   
   A `Closure<Integer>` returned for `Supplier<String>` is still an error. This 
PR, #3113 (GROOVY-12588) and #3126 (GROOVY-12599) each add an 
`isClosureCoercibleToSAM` helper; whichever lands later should fold its copy 
into the one already on master.
   
   ## Tests
   
   `CoercionSTCTest.testCoerceClosureReturnToFunctionalInterface` fails without 
the change, under both `CoercionSTCTest` and `CoercionStaticCompileTests`. Its 
lambda cases fail under static compilation without the 
`StaticTypesLambdaWriter` change. 
`testCoerceClosureReturnToFunctionalInterface2` checks that mismatched return 
types are still rejected. The `groovy.transform.stc`, 
`org.codehaus.groovy.classgen.asm.sc`, `groovy.bugs` and `gls` tests pass. The 
Checkstyle and CodeNarc gates pass.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to