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 2021/10/12 15:30:44 UTC

[groovy] 02/02: GROOVY-10222: STC: restore generic method returns generics method result

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

commit 4d5c95d3c355fd59217cbf95f1756773e7f2363b
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Oct 12 10:30:28 2021 -0500

    GROOVY-10222: STC: restore generic method returns generics method result
    
    ~GROOVY-7720~
---
 .../transform/stc/StaticTypeCheckingSupport.java   | 12 ++----
 .../stc/ArraysAndCollectionsSTCTest.groovy         |  7 ----
 .../groovy/transform/stc/GenericsSTCTest.groovy    | 44 +++++++++++++++++++++-
 3 files changed, 46 insertions(+), 17 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 3ef1dd0..e30ff75 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -667,15 +667,6 @@ public abstract class StaticTypeCheckingSupport {
             return true;
         }
 
-        // GROOVY-7307, GROOVY-9952, et al.
-        if (left.isGenericsPlaceHolder()) {
-            GenericsType[] genericsTypes = left.getGenericsTypes();
-            // should always be the case, but better safe than sorry
-            if (genericsTypes != null && genericsTypes.length == 1) {
-                return genericsTypes[0].isCompatibleWith(right);
-            }
-        }
-
         if (left.isArray()) {
             if (right.isArray()) {
                 return checkCompatibleAssignmentTypes(left.getComponentType(), right.getComponentType(), rightExpression, false);
@@ -753,6 +744,9 @@ public abstract class StaticTypeCheckingSupport {
             return true;
         }
 
+        if (left.isGenericsPlaceHolder()) {
+            return left.getGenericsTypes()[0].isCompatibleWith(right);
+        }
         // GROOVY-7316, GROOVY-10256: "Type x = m()" given "def <T> T m()"; T adapts to target
         return right.isGenericsPlaceHolder() && right.asGenericsType().isCompatibleWith(left);
     }
diff --git a/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy b/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy
index e425ab7..d86840c 100644
--- a/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy
@@ -66,13 +66,6 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase {
                 new X[]{new C<Number, String>()}
             }
         '''
-        shouldFailWithMessages '''
-            class C<X, Y> {
-            }
-            def <X extends C<Number, String>> X[] m() {
-                new X[]{new C<Object, String>()}
-            }
-        ''', 'Cannot convert from C<java.lang.Object, java.lang.String> to X'
     }
 
     void testConvertibleTypesInArrayInitializer() {
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index 6ed4581..50e5272 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -498,6 +498,25 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    // GROOVY-10222
+    void testReturnTypeInferenceWithMethodGenerics19() {
+        assertScript '''
+            class Task {
+                def <T> T exec(args) {
+                    args
+                }
+            }
+            class Test {
+                Task task
+                def <T> T exec(args) {
+                    task.exec(args) // Cannot return value of type #T on method returning type T
+                }
+            }
+            String result = new Test(task: new Task()).exec('works')
+            assert result == 'works'
+        '''
+    }
+
     void testDiamondInferrenceFromConstructor1() {
         assertScript '''
             class Foo<U> {
@@ -1016,6 +1035,20 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    // GROOVY-10222
+    void testAssignmentShouldWorkForParameterizedType() {
+        assertScript '''
+            class C<T> {
+                def <X> X m() {
+                }
+                void test() {
+                    T x = m() // Cannot assign value of type #X to variable of type T
+                }
+            }
+            new C().test()
+        '''
+    }
+
     // GROOVY-9555
     void testAssignmentShouldWorkForProperUpperBound() {
         assertScript '''
@@ -2226,7 +2259,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
         '#test(int, java.lang.String). Please check if the declared type is correct and if the method exists.'
     }
 
-    // GROOVY-7720
+    @NotYetImplemented // GROOVY-7720
     void testIncompatibleArgumentsForPlaceholders2() {
         shouldFailWithMessages '''
             class Consumer<T> {
@@ -2245,6 +2278,15 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
             }
         ''',
         'Cannot return value of type T on method returning type U'
+
+        shouldFailWithMessages '''
+            class C<X, Y> {
+            }
+            def <X extends C<Number, String>> X[] m() {
+                new X[]{new C<Object, String>()}
+            }
+        ''',
+        'Cannot convert from C<java.lang.Object, java.lang.String> to X'
     }
 
     // GROOVY-9902: incomplete generics should not stop type checking