[
https://issues.apache.org/jira/browse/GROOVY-12564?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18134405#comment-18134405
]
ASF GitHub Bot commented on GROOVY-12564:
-----------------------------------------
codeconsole opened a new pull request, #3093:
URL: https://github.com/apache/groovy/pull/3093
A closure whose return type is an intersection, such as the value of `flag ?
1 : 'x'`, `this` in a `@SelfType` trait, or a variable narrowed by two
instanceof checks, is typed `Closure<? extends A & B>`. Calling it through a
variable, `inner()` or `inner.call()`, was typed as the wildcard's own
placeholder, named "?". A closure returning that call then got a `doCall`
declared to return the class "?":
```groovy
@CompileStatic
Object make(boolean flag) { def outer = { def inner = { flag ? 1 : 'x' };
inner() }; outer() }
make(true) // NoClassDefFoundError: ?
```
The same held under `@TypeChecked`, in classes and traits, in instance and
static methods and in field initializers. The type checker now types such a
call as the wildcard's upper bound, or the intersection of its bounds, which is
the closure's return type.
## Tests
`ClosuresSTCTest.testCallOfClosureReturningIntersectionType`, also run
statically compiled, fails without the change. 11,626 tests in the `groovy`,
`gls`, `bugs` and STC/SC packages pass, apart from
`testSelfReferentialTypeParameter5`, the `@Grab` race of GROOVY-12527, which
fails the same way on master. The Checkstyle and CodeNarc gates pass.
Seen in 4.0.33, 5.0.8 and 6.0.0.
> STC: calling a closure of intersection type is typed as "?", giving
> NoClassDefFoundError: ?
> -------------------------------------------------------------------------------------------
>
> Key: GROOVY-12564
> URL: https://issues.apache.org/jira/browse/GROOVY-12564
> Project: Groovy
> Issue Type: Bug
> Components: Static Type Checker
> Affects Versions: 4.0.33, 5.0.8, 6.0.0
> Reporter: Scott Murphy Heiberg
> Priority: Major
>
> A closure whose return type is an intersection, such as the value of {{flag ?
> 1 : 'x'}}, is typed {{Closure<? extends A & B>}}. A call of such a closure
> through a variable is typed as the wildcard's placeholder class, named "?". A
> closure returning that call gets a {{doCall}} declared to return class "?":
> {code:groovy}
> @groovy.transform.CompileStatic
> Object make(boolean flag) { def outer = { def inner = { flag ? 1 : 'x' };
> inner() }; outer() }
> make(true) // NoClassDefFoundError: ?
> {code}
> The same under {{@TypeChecked}}, in traits, and in static methods and field
> initializers.
> Expected: the call is typed as the wildcard's upper bound (the closure's
> return type).
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)