[ 
https://issues.apache.org/jira/browse/GROOVY-12588?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18135457#comment-18135457
 ] 

ASF GitHub Bot commented on GROOVY-12588:
-----------------------------------------

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

   Static type checking rejects a value whose static type is `Closure<R>` (not 
a closure literal) when it is assigned to a parameterized functional interface:
   
   ```groovy
   import java.util.function.Supplier
   
   @groovy.transform.CompileStatic
   def m() {
       Closure<String> c = { 'a' }
       Supplier<String> s = c // Incompatible generic argument types. Cannot 
assign groovy.lang.Closure<java.lang.String> to: 
java.util.function.Supplier<java.lang.String>
       s.get()
   }
   ```
   
   Raw `Supplier s = c` and closure literals are accepted, and dynamic Groovy 
coerces the closure. The same error came from properties, subscripts, 
ternaries, field assignments and generic methods whose result is a 
`Closure<R>`, and for SAM types with parameters (`Function<Integer,String>`, 
`Comparator<String>`, ...).
   
   `checkCompatibleAssignmentTypes` already accepts Closure to SAM coercion; 
the generics check that runs after it (`checkTypeGenerics`) compared 
`Closure<String>` with `Supplier<String>` as a plain parameterized subtype and 
failed. It now accepts a `Closure<R>` (or a Closure subclass) when the SAM 
type's abstract method, parameterized by the target type, returns void or a 
type that accepts `R`, using the same test as the return check for closure 
literals. A mismatch such as `Closure<Integer>` to `Supplier<String>` is still 
reported. Static compilation emits the same coercion as for the raw case, so 
the value is converted to the interface.
   
   ## Tests
   
   `CoercionSTCTest.testCoerceToFunctionalInterface22` and 
`testCoerceToFunctionalInterface23` fail without the change, both in 
`CoercionSTCTest` and in `CoercionStaticCompileTests`; 
`testCoerceToFunctionalInterface24` covers the assignments that must stay 
errors. `groovy.transform.stc.*`, `org.codehaus.groovy.classgen.asm.sc.*`, 
`groovy.bugs.*` and `gls.*` pass. The Checkstyle and CodeNarc gates pass.
   
   
   Seen in 4.0.33, 5.0.8 and 6.0.0.
   




> STC rejects a Closure<R> value assigned to a parameterized functional 
> interface ("Incompatible generic argument types")
> -----------------------------------------------------------------------------------------------------------------------
>
>                 Key: GROOVY-12588
>                 URL: https://issues.apache.org/jira/browse/GROOVY-12588
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 4.0.33, 5.0.8, 6.0.0
>            Reporter: Scott Murphy Heiberg
>            Priority: Major
>
> {code:groovy}
> import java.util.function.Supplier
> @groovy.transform.TypeChecked // or @CompileStatic
> def m() {
>     Closure<String> c = { 'a' }
>     Supplier<String> s = c
>     s.get()
> }
> assert m() == 'a'
> {code}
> Actual result:
> {noformat}
> [Static type checking] - Incompatible generic argument types. Cannot assign 
> groovy.lang.Closure<java.lang.String> to: 
> java.util.function.Supplier<java.lang.String>
> {noformat}
> Expected result: the script compiles and the closure is coerced to the 
> interface, as it is for a closure literal, for a raw target ({{Supplier s = 
> c}}) and in dynamic Groovy.
> The same error is reported when the value comes from a property, a subscript, 
> a field assignment or a generic method returning a Closure, and for SAM types 
> with parameters such as {{Function<Integer,String>}}. The assignment check 
> accepts Closure to SAM coercion, but the generics check that follows it 
> compares {{Closure<String>}} with {{Supplier<String>}} as if Closure had to 
> implement the interface.
> Seen in 4.0.33, 5.0.8, 6.0.0 and master.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to