[ https://issues.apache.org/jira/browse/GROOVY-11341?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Peter Schmitz updated GROOVY-11341: ----------------------------------- Description: 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 getValueMethod = 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 was: 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 getValueMethod = 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 > @CompileStatic: Compilation fails due to a synthetic bridge method in the > subclass > ---------------------------------------------------------------------------------- > > 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: 2.4.x, 2.5.x, 3.0.21, 5.0.0-alpha-7, 4.0.20 > Reporter: Peter Schmitz > Priority: Minor > Labels: CompileStatic, groovyc > > 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 getValueMethod = 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 -- This message was sent by Atlassian Jira (v8.20.10#820010)