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)

Reply via email to