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/22 17:00:14 UTC

[jira] [Commented] (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 commented on GROOVY-10250:
--------------------------------------

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
>            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)