You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2022/09/13 17:16:33 UTC

[groovy] 02/02: GROOVY-10315, GROOVY-10317: STC: merge multiple witnesses for type param of method

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

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

commit dc14af29347912bcbf89fa5dbff303b40e5bf01f
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Sep 13 12:06:20 2022 -0500

    GROOVY-10315, GROOVY-10317: STC: merge multiple witnesses for type param
    of method
---
 .../transform/stc/StaticTypeCheckingSupport.java   | 23 +++++++++++++++-------
 .../groovy/transform/stc/GenericsSTCTest.groovy    | 21 +++++++++++++++++++-
 2 files changed, 36 insertions(+), 8 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 3bcb9c1062..3bd4db3dd4 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -468,11 +468,7 @@ public abstract class StaticTypeCheckingSupport {
             }
             return true;
         }
-        if (type.isDerivedFrom(CLOSURE_TYPE) && isSAMType(toBeAssignedTo)) {
-            return true;
-        }
-
-        return false;
+        return (type.isDerivedFrom(CLOSURE_TYPE) && isSAMType(toBeAssignedTo));
     }
 
     static boolean isVargs(final Parameter[] parameters) {
@@ -644,6 +640,11 @@ public abstract class StaticTypeCheckingSupport {
         return checkCompatibleAssignmentTypes(left, right, rightExpression, true);
     }
 
+    /**
+     * Everything that can be done by {@code castToType} should be allowed for assignment.
+     *
+     * @see org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation#castToType(Object,Class)
+     */
     public static boolean checkCompatibleAssignmentTypes(final ClassNode left, final ClassNode right, final Expression rightExpression, final boolean allowConstructorCoercion) {
         if (!isPrimitiveType(left) && isNullConstant(rightExpression)) {
             return true;
@@ -823,7 +824,7 @@ public abstract class StaticTypeCheckingSupport {
                     return !Double.valueOf(val).equals(number);
                 }
                 default: // double
-                    return false; // no possible loose here
+                    return false; // no possible loss here
             }
         }
         return true; // possible loss of precision
@@ -885,7 +886,7 @@ public abstract class StaticTypeCheckingSupport {
         if (type.isArray() && superOrInterface.isArray()) {
             return implementsInterfaceOrIsSubclassOf(type.getComponentType(), superOrInterface.getComponentType());
         }
-        if (GROOVY_OBJECT_TYPE.equals(superOrInterface) && !type.isInterface() && isBeingCompiled(type)) {
+        if (superOrInterface.equals(GROOVY_OBJECT_TYPE) && !type.isInterface() && isBeingCompiled(type)) {
             return true;
         }
         return false;
@@ -1603,6 +1604,14 @@ public abstract class StaticTypeCheckingSupport {
                     GenericsTypeName name = new GenericsTypeName(oldValue.getName());
                     GenericsType newValue = connections.get(name); // find "V" in T=V
                     if (newValue == oldValue) continue;
+                    if (newValue == null) {
+                        newValue = connections.get(entry.getKey());
+                        if (newValue != null) { // GROOVY-10315, GROOVY-10317
+                            ClassNode o = GenericsUtils.makeClassSafe0(CLASS_Type, oldValue),
+                                      n = GenericsUtils.makeClassSafe0(CLASS_Type, newValue);
+                            newValue = WideningCategories.lowestUpperBound(o,n).getGenericsTypes()[0];
+                        }
+                    }
                     if (newValue == null) {
                         entry.setValue(newValue = applyGenericsContext(connections, oldValue));
                         checkForMorePlaceholders = checkForMorePlaceholders || !equalIncludingGenerics(oldValue, newValue);
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index da8b9dba83..2dce5be83f 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -2392,7 +2392,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
 
     // GROOVY-10315
     void testShouldUseMethodGenericType14() {
-        for (args in ['m2(), c.m()'/*, 'c.m(), m2()'*/]) {
+        for (args in ['m2(), c.m()', 'c.m(), m2()']) {
             assertScript """
                 class C<T> {
                     def T m() {
@@ -2410,6 +2410,25 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
         }
     }
 
+    // GROOVY-10317
+    void testShouldUseMethodGenericType14a() {
+        assertScript '''
+            class B {
+                def <X> X m() {
+                }
+            }
+            class C<Y,Z> {
+                void p(Y y) {
+                }
+                void test() {
+                    def b = new B()
+                    (new C<Z,Z>()).p(b.m())
+                }
+            }
+            new C().test()
+        '''
+    }
+
     // GROOVY-10364
     void testShouldUseMethodGenericType15() {
         assertScript '''