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


The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push:
     new 58fb254  GROOVY-10320: check placeholder compatibility without wildcard
58fb254 is described below

commit 58fb2546cdf11a199462cb776d020d8ddada627a
Author: Eric Milles <[email protected]>
AuthorDate: Tue Oct 19 14:08:33 2021 -0500

    GROOVY-10320: check placeholder compatibility without wildcard
---
 .../java/org/codehaus/groovy/ast/GenericsType.java | 23 ++++++++--------
 .../transform/stc/StaticTypeCheckingSupport.java   |  9 ++----
 .../groovy/transform/stc/GenericsSTCTest.groovy    | 32 ++++++++++++++++++++++
 3 files changed, 46 insertions(+), 18 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/ast/GenericsType.java 
b/src/main/java/org/codehaus/groovy/ast/GenericsType.java
index ba8dc5d..378b054 100644
--- a/src/main/java/org/codehaus/groovy/ast/GenericsType.java
+++ b/src/main/java/org/codehaus/groovy/ast/GenericsType.java
@@ -206,21 +206,20 @@ public class GenericsType extends ASTNode {
             if (genericsTypes == null) {
                 return true;
             }
-            if (isWildcard()) {
-                if (getLowerBound() != null) {
-                    ClassNode lowerBound = getLowerBound();
-                    return 
genericsTypes[0].name.equals(lowerBound.getUnresolvedName());
+            String name0 = genericsTypes[0].getName();
+            if (!isWildcard()) {
+                return name0.equals(getName());
+            }
+            if (getLowerBound() != null) {
+                if (name0.equals(getLowerBound().getUnresolvedName())) {
+                    return true;
                 }
-                if (getUpperBounds() != null) {
-                    for (ClassNode upperBound : getUpperBounds()) {
-                        if 
(genericsTypes[0].name.equals(upperBound.getUnresolvedName())) {
-                            return true;
-                        }
-                    }
-                    return false;
+            } else if (getUpperBounds() != null) {
+                if (name0.equals(getUpperBounds()[0].getUnresolvedName())) {
+                    return true;
                 }
             }
-            return genericsTypes[0].name.equals(name);
+            return checkGenerics(classNode);
         }
         if (isWildcard() || isPlaceholder()) {
             // if the generics spec is a wildcard or a placeholder then check 
the bounds
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 ddc4419..4069ff6 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -458,15 +458,12 @@ public abstract class StaticTypeCheckingSupport {
             return true;
         }
         if (implementsInterfaceOrIsSubclassOf(type, toBeAssignedTo)) {
-            if (toBeAssignedTo.getGenericsTypes() != null) {
-                // perform additional check on generics
-                // ? extends toBeAssignedTo
-                GenericsType gt = 
GenericsUtils.buildWildcardType(toBeAssignedTo);
+            if (toBeAssignedTo.getGenericsTypes() != null) { // perform 
additional check on generics
+                GenericsType gt = toBeAssignedTo.isGenericsPlaceHolder() ? 
toBeAssignedTo.getGenericsTypes()[0] : 
GenericsUtils.buildWildcardType(toBeAssignedTo);
                 return gt.isCompatibleWith(type);
             }
             return true;
         }
-        // SAM check
         if (type.isDerivedFrom(CLOSURE_TYPE) && isSAMType(toBeAssignedTo)) {
             return true;
         }
@@ -1419,7 +1416,7 @@ public abstract class StaticTypeCheckingSupport {
         applyGenericsConnections(classGTs, resolvedMethodGenerics);
         // and then start our checks with the receiver
         if (!skipBecauseOfInnerClassNotReceiver) {
-            failure = failure || inferenceCheck(Collections.emptySet(), 
resolvedMethodGenerics, candidateMethod.getDeclaringClass(), receiver, false);
+            failure = inferenceCheck(Collections.emptySet(), 
resolvedMethodGenerics, candidateMethod.getDeclaringClass(), receiver, false);
         }
         // the outside context parts till now define placeholder we are not 
allowed to
         // generalize, thus we save that for later use...
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy 
b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index 9a5faa0..1ef7b24 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -1760,6 +1760,38 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase 
{
         '''
     }
 
+    // GROOVY-10320
+    void testPlusOverload() {
+        assertScript '''
+            interface I<T extends I> {
+                T plus(T t_aka_i)
+            }
+            @groovy.transform.TupleConstructor(defaults=false)
+            class C implements I<C> {
+                final BigDecimal n
+                @Override
+                C plus(C c) {
+                    if (!c) return this
+                    new C((n ?: 0.0) + (c.n ?: 0.0))
+                }
+            }
+
+            def <X extends I> X test(List<X> items) {
+                X total = null
+                for (it in items) {
+                    if (!total)
+                        total = it
+                    else
+                        total += it // Cannot call X#plus(T) with arguments [X]
+                }
+                total
+            }
+
+            def total = test([new C(1.1), new C(2.2)])
+            assert total.n == 3.3
+        '''
+    }
+
     void testShouldNotCreateStackOverflow() {
         assertScript '''
             class Element {

Reply via email to