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/09/06 13:08:03 UTC

[groovy] branch GROOVY_2_5_X updated: GROOVY-10098: STC: infer return type from Closure for short-form call

This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch GROOVY_2_5_X
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/GROOVY_2_5_X by this push:
     new 3d709e431d GROOVY-10098: STC: infer return type from Closure<T> for short-form call
3d709e431d is described below

commit 3d709e431d8fef7b6b9c92bdfbf3b6c9a91993e3
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu May 20 12:45:51 2021 -0500

    GROOVY-10098: STC: infer return type from Closure<T> for short-form call
---
 .../transform/stc/StaticTypeCheckingVisitor.java   | 12 +++---
 .../groovy/transform/stc/GenericsSTCTest.groovy    | 48 +++++-----------------
 2 files changed, 17 insertions(+), 43 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index 1325eee92a..95298fe936 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -3486,13 +3486,13 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                             typeCheckClosureCall(callArguments, args, parameters);
                         }
                         ClassNode type = getType(((ASTNode) variable));
-                        if (type != null && type.equals(CLOSURE_TYPE)) {
+                        if (CLOSURE_TYPE.equals(type)) { // GROOVY-10098, et al.
                             GenericsType[] genericsTypes = type.getGenericsTypes();
-                            type = OBJECT_TYPE;
-                            if (genericsTypes != null) {
-                                if (!genericsTypes[0].isPlaceholder()) {
-                                    type = genericsTypes[0].getType();
-                                }
+                            if (genericsTypes != null && genericsTypes.length == 1
+                                    && genericsTypes[0].getLowerBound() == null) {
+                                type = getCombinedBoundType(genericsTypes[0]);
+                            } else {
+                                type = OBJECT_TYPE;
                             }
                         }
                         if (type != null) {
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index 91d80ea251..bee56d40e3 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -284,44 +284,18 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    @NotYetImplemented // GROOVY-10646
-    void testReturnTypeInferenceWithMethodGenerics28() {
-        String types = '''
-            class Model {
-            }
-            interface Output<T> {
-                T getT()
-            }
-            abstract class WhereDSL<Type> {
-                abstract Type where()
-            }
-            abstract class Input<T> extends WhereDSL<ReferencesOuterClassTP> {
-                class ReferencesOuterClassTP implements Output<T> {
-                    @Override T getT() { return null }
-                }
-            }
-        '''
-        assertScript types + '''
-            void m(Input<Model> input) {
-                def output = input.where()
-                @ASTTest(phase=INSTRUCTION_SELECTION, value={
-                    assert node.getNodeMetaData(INFERRED_TYPE).toString(false) == 'Model'
-                })
-                def result = output.getT()
-            }
-        '''
-        assertScript types + '''
-            @FunctionalInterface
-            interface Xform extends java.util.function.Function<Input<Model>, Output<Model>> {
-            }
-
-            void select(Xform xform) {
-            }
-
-            select { input ->
-                def result = input.where()
-                return result // Cannot return value of type Input$ReferencesOuterClassTP for closure expecting Output<Model>
+    // GROOVY-10098
+    void testReturnTypeInferenceWithMethodGenerics16() {
+        assertScript '''
+            @groovy.transform.TupleConstructor(defaults=false)
+            class C<T extends Number> {
+              T p
+              T m() {
+                Closure<T> x = { -> p }
+                x() // Cannot return value of type Object on method returning type T
+              }
             }
+            assert new C<>(42).m() == 42
         '''
     }