You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@groovy.apache.org by Hannes Greule <ha...@outlook.de> on 2023/01/04 08:42:05 UTC

Static Type Checking selects wrong method

Hi,

I encountered an issue with @CompileStatic. Consider following code:

import groovy.transform.CompileStatic

@CompileStatic
class E extends BImpl {
    @Override
    public void a() {
        super.a();
    }
    public static void main(String[] args) { }
}
interface A {
    void a();
}
interface B extends A {
    @Override
    void a();
}
class AImpl implements A {
    @Override
    public void a() {
    }
}
class BImpl extends AImpl implements B {
}

It will fail to run with the following error:

Bug.groovy: 7: [Static type checking] - Abstract method a() cannot be called directly
@ line 7, column 9.
           super.a();
           ^

However, without @CompileStatic this code runs just fine.
It also works in Java, as the called super method comes from AImpl, but STC in Groovy selects the abstract method from B instead.
This seems to be caused by https://github.com/apache/groovy/blob/ea6ba7c6fcfefe3d8abdfbb6e20a44b1ebb8823e/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java#L1091
where the distance to the interface is 1, but the distance to the class is 4.

To give more context: I initially encountered this issue when extending AbstractSet, overriding addAll for a fast path and delegating to super.addAll for the slow path. I think such a pattern is quite common.

Greetings,
Hannes