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/01/30 17:23:20 UTC

[groovy] branch GROOVY_3_0_X updated: GROOVY-10051: STC: fully resolve "T extends Number" to Number not Object

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 35585bb  GROOVY-10051: STC: fully resolve "T extends Number" to Number not Object
35585bb is described below

commit 35585bb78a1c46560a3426596d71f2b29cc97ada
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu Apr 22 14:44:48 2021 -0500

    GROOVY-10051: STC: fully resolve "T extends Number" to Number not Object
    
    Conflicts:
    	src/test/groovy/transform/stc/GenericsSTCTest.groovy
---
 .../transform/stc/StaticTypeCheckingSupport.java   |  2 +-
 .../groovy/transform/stc/GenericsSTCTest.groovy    | 37 ++++++++++++++++++++++
 2 files changed, 38 insertions(+), 1 deletion(-)

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 5a63f55..99b40b2 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -1602,7 +1602,7 @@ public abstract class StaticTypeCheckingSupport {
         }
         // For a placeholder, a type based on the generics type is used for the compatibility check, to match on
         // the actual bounds and not the name of the placeholder.
-        ClassNode replacementType = OBJECT_TYPE;
+        ClassNode replacementType = gt.getType().redirect();
         if (gt.getType().getGenericsTypes() != null) {
             GenericsType realGt = gt.getType().getGenericsTypes()[0];
             if (realGt.getLowerBound() != null) {
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index ce74806..03f9aa5 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -252,6 +252,43 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    // GROOVY-10051
+    void testReturnTypeInferenceWithMethodGenerics6() {
+        assertScript '''
+            abstract class State<H extends Handle> {
+                // Why not return HandleContainer<H>? I can't really say.
+                def <T extends Handle> HandleContainer<T> getHandleContainer(key) {
+                }
+            }
+            class HandleContainer<H extends Handle> {
+                H handle
+            }
+            interface Handle {
+                Result getResult()
+            }
+            class Result {
+                int itemCount
+                String[] items
+            }
+
+            List<String> getStrings(State state, List keys) {
+                keys.collectMany { key ->
+                    List<String> strings = Collections.emptyList()
+                    def container = state.getHandleContainer(key) // returns HandleContainer<Object> not HandleContainer<SearchHandle>
+                    if (container != null) {
+                        def result = container.handle.result
+                        if (result != null && result.itemCount > 0) {
+                            strings = Arrays.asList(result.items)
+                        }
+                    }
+                    strings
+                }
+            }
+
+            assert getStrings(null,[]).isEmpty()
+        '''
+    }
+
     void testDiamondInferrenceFromConstructor1() {
         assertScript '''
             Set< Long > s2 = new HashSet<>()