Search code examples
groovytype-inferencereturn-typetypechecking

Groovy doesn't infer the return type of a method


I'm trying to type check a simple Groovy script:

@groovy.transform.TypeChecked
class C {
    def fn() { return "result" }
    def ln() { return fn().length() }
}
new C().ln()

My expectation would be that the fn method's would be inferred to String, however when I try to run the script I get an error:

_GroovyUserScript_: 4: [Static type checking] - Cannot find matching method java.lang.Object#length(). Please check if the declared type is correct and if the method exists.
 @ line 4, column 23.
       def ln() { return fn().length() }
                         ^

1 error

Meaning the return type for the method was inferred to be java.lang.Object. Now, if I change the script to

@groovy.transform.TypeChecked
    ...
    String fn() { return "result" }
    ...

the script is compiled correctly.

However, I've noticed that the following script also compiles correctly:

@groovy.transform.TypeChecked
class C {
    def fn() { return "result" }
}
def x() {
    new C().fn().length()
}
x()

So maybe the problem is that type inference is not transitive between methods of the same class for some reason?


Solution

  • In groovy def equals to Object so, the first case correctly fails.

    And @groovy.transform.TypeChecked checks only class or method that it annotates. in second case the method def x(){...} is not annotated (it's declared out of class). So, no validation performed at compilation step.