This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new dd37d71e97 GROOVY-11341, GROOVY-11746: multi-level covariant and 
synthetic
dd37d71e97 is described below

commit dd37d71e9739a6ad3219c76643ea1f7d8bb33a49
Author: Eric Milles <[email protected]>
AuthorDate: Fri Sep 5 09:42:23 2025 -0500

    GROOVY-11341, GROOVY-11746: multi-level covariant and synthetic
---
 .../transform/stc/StaticTypeCheckingSupport.java   | 12 +++++++----
 .../groovy/transform/stc/MethodCallsSTCTest.groovy | 23 ++++++++++++++++++++++
 2 files changed, 31 insertions(+), 4 deletions(-)

diff --git 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index 5b7128988c..ea9de4082b 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -1213,13 +1213,17 @@ public abstract class StaticTypeCheckingSupport {
                         }
                     } else if (!oneDC.equals(twoDC)) {
                         if 
(ParameterUtils.parametersEqual(one.getParameters(), two.getParameters())) {
-                            // GROOVY-11341, GROOVY-11746: multi-level 
covariant and synthetic override
-                            if 
(!one.getReturnType().equals(two.getReturnType())) {
-                                
toBeRemoved.add(isCovariant(two.getReturnType(), one.getReturnType()) ? one : 
two);
-                            } else
                             // GROOVY-6882, GROOVY-6970: drop overridden or 
interface equivalent method
                             if (!twoDC.isInterface() ? 
oneDC.isDerivedFrom(twoDC) : oneDC.implementsInterface(twoDC) || // 
GROOVY-10897: concrete vs. abstract
                                                                                
     (!disjoint && !one.isAbstract() && !(two instanceof ExtensionMethodNode))) 
{
+                                // GROOVY-10109, GROOVY-11341, GROOVY-11746: 
multi-level covariant and synthetic overrides
+                                if (isSynthetic(one, two) && !two.isAbstract() 
&& !(two instanceof ExtensionMethodNode)) {
+                                    ClassNode oneRT = one.getReturnType(), 
twoRT = two.getReturnType();
+                                    if (!oneRT.equals(twoRT) && 
isCovariant(twoRT, oneRT)) {
+                                        toBeRemoved.add(one); // edge case: 
two is covariant
+                                        continue;
+                                    }
+                                }
                                 toBeRemoved.add(two);
                             } else if (oneDC.isInterface() ? (disjoint ? 
twoDC.implementsInterface(oneDC) : twoDC.isInterface()) : 
twoDC.isDerivedFrom(oneDC)) {
                                 toBeRemoved.add(one);
diff --git a/src/test/groovy/groovy/transform/stc/MethodCallsSTCTest.groovy 
b/src/test/groovy/groovy/transform/stc/MethodCallsSTCTest.groovy
index b9f068fad7..2b430400eb 100644
--- a/src/test/groovy/groovy/transform/stc/MethodCallsSTCTest.groovy
+++ b/src/test/groovy/groovy/transform/stc/MethodCallsSTCTest.groovy
@@ -1992,6 +1992,29 @@ class MethodCallsSTCTest extends 
StaticTypeCheckingTestCase {
         }
     }
 
+    // GROOVY-11341, GROOVY-11746
+    void testInterfaceExtensionMethodIsCovariant() {
+        assertScript '''
+            class Thing extends Tuple {
+                Thing() {
+                    super(new Object[0])
+                }
+                def getAt(String name) {
+                    name
+                }
+                void test() {
+                    @ASTTest(phase=INSTRUCTION_SELECTION, value={
+                        def md = 
node.rightExpression.getNodeMetaData(DIRECT_METHOD_CALL_TARGET)
+                        assert md.declaringClass.nameWithoutPackage == 'Thing' 
// not Collection
+                    })
+                    def foo = getAt('foo')
+                }
+            }
+            def thing = new Thing()
+            thing[''] == ''
+        '''
+    }
+
     // GROOVY-7987
     void testNonStaticMethodViaStaticReceiver() {
         shouldFailWithMessages '''

Reply via email to