Peter Schmitz created GROOVY-11341: -------------------------------------- Summary: @CompileStatic: Compilation fails due to synthetic bridge methods (probably) Key: GROOVY-11341 URL: https://issues.apache.org/jira/browse/GROOVY-11341 Project: Groovy Issue Type: Bug Components: Static compilation, Static Type Checker Affects Versions: 4.0.20, 5.0.0-alpha-7, 3.0.21, 2.4.x, 2.5.x Reporter: Peter Schmitz
Given the following Java classes: {code:java} public interface InterfaceBase { Object getValue(); } public class MyImplBase { public Long getValue() { return 42L; } } public class MyImpl extends MyImplBase implements InterfaceBase { } {code} And the following SimpleCaller.groovy: {code:java} @groovy.transform.CompileStatic class SimpleCaller { public static void main(String[] args) { Long v = new MyImpl().getValue(); System.out.println(v); //42 } } {code} The compilation fails with: {{SimpleCaller.groovy: 7: [Static type checking] - Cannot assign value of type java.lang.Object to variable of type java.lang.Long}} {{ @ line 7, column 16.}} {{ Long v = new MyImpl().getValue();}} {{ ^}} Compiling the equivalent {{SimpleCaller.java}} with _javac_ completes successfully. This structure is a bit uncommon, because MyImplBase uses a covariant return type and doesn't implement the interface directly, only its subclass does. I believe the problem is connected to the synthetic bridge method inserted into the bytecode of {_}MyImpl{_}, which is picked up and preferred by _groovyc_ over the non-synthetic method in {_}MyImplBase{_}. In case this is related: The synthetic bridge method is selected when using reflection as well, causing the inferred type by javac and reflection to diverge: {code:java} Method getNumber = MyImpl.class.getMethod("getValue"); // public java.lang.Object MyImpl.getValue() {code} Workarounds: * Disable static compilation * An explicit cast to Long in SimpleCaller. * Explicitly repeat the method signature by repeating the method signature * If possible, add/Move the implements to MyImplBase - then the synthetic method is in the same class as the real one, which _groovyc_ is able to detect. Using generics in the Interface doesn't work either (probably due to type erasure). Seems to be a more generalized issue when compared to the similar [GROOVY-5003|https://issues.apache.org/jira/browse/GROOVY-5003] -- This message was sent by Atlassian Jira (v8.20.10#820010)