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/03/13 16:51:07 UTC

[groovy] branch master updated: GROOVY-10499: LUB of type args `Type` and `? extends Type` yields `Type`

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 a99c698  GROOVY-10499: LUB of type args `Type` and `? extends Type` yields `Type`
a99c698 is described below

commit a99c6980da68cbc3705d90e2c4eae43fa5320304
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun Mar 13 11:35:43 2022 -0500

    GROOVY-10499: LUB of type args `Type` and `? extends Type` yields `Type`
---
 .../transform/stc/StaticTypeCheckingSupport.java   |  7 +++++--
 .../groovy/transform/stc/GenericsSTCTest.groovy    | 22 ++++++++++++++++++++++
 2 files changed, 27 insertions(+), 2 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 ce00d87..cf3e035 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -1920,10 +1920,13 @@ public abstract class StaticTypeCheckingSupport {
         return genericsType.getType();
     }
 
-    static GenericsType getCombinedGenericsType(final GenericsType gt1, final GenericsType gt2) {
+    static GenericsType getCombinedGenericsType(GenericsType gt1, GenericsType gt2) {
+        // GROOVY-9998, GROOVY-10499: unpack "?" that is from "? extends T"
+        if (isUnboundedWildcard(gt1)) gt1 = gt1.getType().asGenericsType();
+        if (isUnboundedWildcard(gt2)) gt2 = gt2.getType().asGenericsType();
         ClassNode cn1 = GenericsUtils.makeClassSafe0(CLASS_Type, gt1);
         ClassNode cn2 = GenericsUtils.makeClassSafe0(CLASS_Type, gt2);
-        ClassNode lub = lowestUpperBound(cn1,cn2);
+        ClassNode lub = lowestUpperBound(cn1, cn2);
         return lub.getGenericsTypes()[0];
     }
 
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index 2e91b70..5a88260 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -2559,6 +2559,28 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
         }
     }
 
+    // GROOVY-10499
+    void testCompatibleArgumentsForPlaceholders7() {
+        ['?', 'Y', '? extends Y'].each {
+            assertScript """
+                class Foo<X> {
+                    Foo(X x) {
+                    }
+                }
+                class Bar<Y> {
+                    Bar(Foo<${it}> foo, Y y) {
+                    }
+                    Y baz(Y y) {
+                    }
+                }
+                def <Z> void test(Z z = null) {
+                    new Bar<>(new Foo<Z>(z), z).baz(z) // Cannot find matching method Bar#baz(Z)
+                }
+                test()
+            """
+        }
+    }
+
     void testIncompatibleArgumentsForPlaceholders1() {
         shouldFailWithMessages '''
             def <T extends Number> T test(T one, T two) { }