You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Eric Milles (Jira)" <ji...@apache.org> on 2021/09/26 17:39:00 UTC
[jira] [Comment Edited] (GROOVY-10250) Erroneous type inference of
closure in STC
[ https://issues.apache.org/jira/browse/GROOVY-10250?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17418717#comment-17418717 ]
Eric Milles edited comment on GROOVY-10250 at 9/26/21, 5:38 PM:
----------------------------------------------------------------
I can confirm that 3.0.9 is inferring {{Either<Closure<URI>,Foo>}} and 4.0b1 is inferring {{Either<URI,Foo>}}. So the method selection has changed. I will try to determine if it is the MOP or STC selection algorithm that is responsible for this difference.
Here is a small version:
{code:groovy}
class Config {
URI defaultUri
URI toURI(String s) {}
}
class Either<X,Y> {
def <Z> Either<X,Z> map(java.util.function.Function<? super Y, ? extends Z> fn) {
}
}
interface Option<T> {
default <L> Either<L, T> toEither(L left) {
}
default <L> Either<L, T> toEither(java.util.function.Supplier<? extends L> leftSupplier) {
}
}
groovy.transform.TypeChecked
void groovy10250(Config config, Option<String> option) {
def either = option.toEither(config.&getDefaultUri).map(config.&toURI)
}
{code}
was (Author: emilles):
Can you run your test(s) with 4.0b1? I withheld generics and meta-object-protocol changes from 3.0.9 in favor of stability. If a specific change can be singled out, it may be reasonable to backport it.
> Erroneous type inference of closure in STC
> ------------------------------------------
>
> Key: GROOVY-10250
> URL: https://issues.apache.org/jira/browse/GROOVY-10250
> Project: Groovy
> Issue Type: Bug
> Components: Static Type Checker
> Affects Versions: 3.0.9
> Reporter: Christopher Smith
> Assignee: Eric Milles
> Priority: Major
> Attachments: SubscriptionClickController.class
>
>
> Sorry if this is a duplicate, but I couldn't identify it. I'm using the Vavr Option and Either types here:
> {code}
> repository.findOne(id) // <- Option<Foo>
> .toEither(config.&defaultUri) // <- Either<URI, Foo>
> .map(linkProvider.&forFoo) // <- Either<URI, URI>
> ...
> {code}
> This is the signature of the method being called:
> {code}
> <L> Either<L, T> toEither(Supplier<? extends L> leftSupplier)
> {code}
> At the invocation of {{toEither}}, the STC appears to correctly recognize that {{config.&defaultUri}} is a valid match for {{Supplier<URI>}} and approves the call. However, instead of inferring {{L=URI}} it infers {{L=Closure<URI>}}, apparently failing to "dereference" the closure into the functional interface, so that later calls expecting {{<URI, URI>}} fail because the STC thinks that Left is a closure.
> Inserting a type witness at {{toEither}} *does* seem to work, which I think is new with 3.0.9.
> **Update:** Optimism apparently premature. The problem appears to be that in fact [{{toEither}} is overloaded|https://github.com/vavr-io/vavr/blob/v0.10.3/vavr/src/main/java/io/vavr/Value.java#L1205-L1227], and the static compiler is selecting the immediate-value override instead of the {{Supplier}} override.
> Bizarrely (I would open a second ticket on this but have no idea how to cleanly repro), when I changed {{.&}} to {{::}} just to see what would happen, I get a {{ClassFormatError}} under GRECLIPSE 4.3.0.v202108132133-e2106 (attached) and a stack overflow under groovyc 3.0.9:
> {code}
> at org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.inferMethodReferenceType (StaticTypeCheckingVisitor.java:3615) at org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.visitMethodCallArguments (StaticTypeCheckingVisitor.java:2750) at org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.inferMethodReferenceType (StaticTypeCheckingVisitor.java:3646) at org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.visitMethodCallArguments (StaticTypeCheckingVisitor.java:2750) at org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.inferMethodReferenceType (StaticTypeCheckingVisitor.java:3646)
> {code}
> Explicitly providing this form _does work_, and appears to be a substantial improvement in 3.0.9's generics handling (is this the partial backport you meant?), because now the entire generic chain infers properly. I note that previously, the STC ignored generics in the {{as}} clause and always treated types as raw, but now it observes them, and I didn't gather this from the release notes.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)