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 2023/03/18 16:05:25 UTC

[groovy] branch master updated: GROOVY-10270: STC: SAM-type (placeholder) accepts closure

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 80cc575af1 GROOVY-10270: STC: SAM-type (placeholder) accepts closure
80cc575af1 is described below

commit 80cc575af1020780b6f7eb999b9924a645b07f95
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Mar 18 11:05:12 2023 -0500

    GROOVY-10270: STC: SAM-type (placeholder) accepts closure
---
 .../transform/stc/StaticTypeCheckingSupport.java       | 11 +++++++----
 src/test/groovy/transform/stc/GenericsSTCTest.groovy   | 18 ++++++++++++++++++
 2 files changed, 25 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 49fbf8380d..fdb2967d71 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -90,6 +90,7 @@ import static org.codehaus.groovy.ast.ClassHelper.GSTRING_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.Integer_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.Long_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.Number_TYPE;
+import static org.codehaus.groovy.ast.ClassHelper.OBJECT;
 import static org.codehaus.groovy.ast.ClassHelper.OBJECT_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.STRING_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.Short_TYPE;
@@ -1551,17 +1552,17 @@ public abstract class StaticTypeCheckingSupport {
 
     private static boolean compatibleConnection(final GenericsType resolved, final GenericsType connection) {
         if (resolved.isPlaceholder()
-                && resolved.getUpperBounds() != null
-                && resolved.getUpperBounds().length == 1
+                &&  resolved.getUpperBounds() != null
+                &&  resolved.getUpperBounds().length == 1
                 && !resolved.getUpperBounds()[0].isGenericsPlaceHolder()
-                && resolved.getUpperBounds()[0].getName().equals("java.lang.Object")) {
+                &&  resolved.getUpperBounds()[0].getName().equals(OBJECT)) {
             return true;
         }
 
         ClassNode resolvedType;
         if (hasNonTrivialBounds(resolved)) {
             resolvedType = getCombinedBoundType(resolved);
-            resolvedType = resolvedType.redirect().getPlainNodeReference();
+            resolvedType = resolvedType.getPlainNodeReference();
         } else if (!resolved.isPlaceholder()) {
             resolvedType = resolved.getType().getPlainNodeReference();
         } else {
@@ -1571,6 +1572,8 @@ public abstract class StaticTypeCheckingSupport {
         GenericsType gt;
         if (connection.isWildcard()) {
             gt = connection;
+        } else if (!connection.isPlaceholder() && connection.getType().equals(CLOSURE_TYPE) && isSAMType(resolvedType)) {
+            return true; // GROOVY-10270: SAM-type (placeholder) accepts closure
         } else { // test compatibility with "? super Type"
             ClassNode lowerBound = connection.getType().getPlainNodeReference();
             if (hasNonTrivialBounds(connection)) {
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index acd936392b..1373132734 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -3358,6 +3358,24 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
         }
     }
 
+    // GROOVY-10270
+    void testCompatibleArgumentsForPlaceholders12() {
+        assertScript '''import java.util.function.*
+            void a(Function<Number,Byte> fn) { }
+            class B {
+                B(Function<Number,Byte> fn) { }
+            }
+            class C<T> {
+                C(T t) { }
+            }
+
+            a({ Number x -> x.byteValue() })
+            new B({ Number x -> x.byteValue() })
+            new C<Function<Number,Byte>>({ Number x -> x.byteValue() } as Function<Number,Byte>)
+            new C<Function<Number,Byte>>({ Number x -> x.byteValue() }                         )
+        '''
+    }
+
     void testIncompatibleArgumentsForPlaceholders1() {
         shouldFailWithMessages '''
             def <T extends Number> T test(T one, T two) { }