Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
2.5.14
Description
I am having trouble migrating a very large project from Groovy 2.4.x to 2.5.14.
I was able to reproduce the problem with this small example:
import groovy.transform.CompileStatic import groovy.transform.SelfType import java.util.function.Supplier @CompileStatic @SelfType([C]) trait D { def go() { String s = foo withObject(s) { s.toUpperCase() } } } @SelfType(B) @CompileStatic trait C {} @SelfType([A]) @CompileStatic trait B {} @CompileStatic trait A { String foo = 'foo' def withObject(String s, Supplier<Object> g) { s + g.get() } } class Impl implements A, B, C, D { def go() { println withObject(foo) { ' bar' } } }
Compiling this code results in this error:
src/main/groovy/bar/Foo.groovy: 13: [Static type checking] - Cannot find matching method <UnionType:bar.C+bar.D>#withObject(java.lang.String, groovy.lang.Closure). Please check if the declared type is correct and if the method exists. @ line 13, column 9. withObject(s) { ^ 1 error
It's easy to work around once you know how: just make the trait that calls `withObject` list the trait that provides that method in its `SelfType` directly, i.e. in this case:
@SelfType([A, C]) trait D { ... }
Interestingly, changing D's self-type to `B` also works! It looks like the 2nd indirection is needed to reproduce the issue.
However, figuring it out can take a long time! Would be nice to make this work automatically, maybe by just making `@SelfType(C)` equivalent to `@SelfType(C, B, A)` (i.e. merge the types by recursively applying other's self-types).