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]