Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
3.0.9
-
None
Description
Sorry if this is a duplicate, but I couldn't identify it. I'm using the Vavr Option and Either types here:
repository.findOne(id) // <- Option<Foo> .toEither(config.&defaultUri) // <- Either<URI, Foo> .map(linkProvider.&forFoo) // <- Either<URI, URI> ...
This is the signature of the method being called:
<L> Either<L, T> toEither(Supplier<? extends L> leftSupplier)
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, 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:
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)
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.