[ 
https://issues.apache.org/jira/browse/GROOVY-11341?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Peter Schmitz updated GROOVY-11341:
-----------------------------------
    Summary: @CompileStatic: Compilation fails due to a synthetic bridge method 
in the subclass  (was: @CompileStatic: Compilation fails due to the synthetic 
bridge method in a subclass)

> @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 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)

Reply via email to