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 2ac70b2db2 GROOVY-10702: STC: reduce inferred types of duck-type 
property access
2ac70b2db2 is described below

commit 2ac70b2db26cd2e0fdbfd63f57fb793cb872a3a3
Author: Eric Milles <[email protected]>
AuthorDate: Sat Dec 27 19:19:50 2025 -0600

    GROOVY-10702: STC: reduce inferred types of duck-type property access
---
 .../transform/stc/StaticTypeCheckingVisitor.java   |  5 +++-
 .../transform/stc/TypeInferenceSTCTest.groovy      | 30 +++++++++-------------
 2 files changed, 16 insertions(+), 19 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 fec219cd57..c5e64d400f 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -1656,12 +1656,15 @@ out:    if ((samParameterTypes.length == 1 && 
isOrImplements(samParameterTypes[0
     on: for (Receiver<String> receiver : receivers) {
             ClassNode receiverType = receiver.getType();
             if (receiverType instanceof UnionTypeClassNode ut) {
+                List<ClassNode> propertyTypes = new ArrayList<>();
+                Consumer<ClassNode> add = 
t->propertyTypes.add(wrapTypeIfNecessary(t));
                 for (ClassNode type : ut.getDelegates()) { // GROOVY-8965, 
GROOVY-10702
                     var copy = (PropertyExpression) 
pexp.transformExpression(ex -> ex);
                     copy.setObjectExpression(varX("_", type));
-                    if (!existsProperty(copy, readMode, null))
+                    if (!existsProperty(copy, readMode, new 
PropertyLookup(type, add)))
                         continue on;
                 }
+                pexp.putNodeMetaData(INFERRED_TYPE, 
lowestUpperBound(propertyTypes));
                 pexp.putNodeMetaData(DYNAMIC_RESOLUTION, Boolean.TRUE);
                 return true;
             }
diff --git a/src/test/groovy/groovy/transform/stc/TypeInferenceSTCTest.groovy 
b/src/test/groovy/groovy/transform/stc/TypeInferenceSTCTest.groovy
index 884423da79..1444495ed3 100644
--- a/src/test/groovy/groovy/transform/stc/TypeInferenceSTCTest.groovy
+++ b/src/test/groovy/groovy/transform/stc/TypeInferenceSTCTest.groovy
@@ -421,42 +421,36 @@ class TypeInferenceSTCTest extends 
StaticTypeCheckingTestCase {
     void testMultipleInstanceOf1() {
         assertScript '''
             class A {
-                void m() {
-                }
+                Float m() { 1 }
             }
             class B {
-                void m() {
-                }
+                Short m() { 3 }
             }
 
-            void test(o) {
+            int foo(o) {
                 if (o instanceof A || o instanceof B) {
-                    o.m()
+                    return o.m().compareTo(2)
                 }
             }
-            test(new A())
-            test(new B())
+            assert foo(new A()) < 0
+            assert foo(new B()) > 0
         '''
 
         assertScript '''
             class A {
-                float getP() {
-                    return 1.0
-                }
+                float getP() { 1 }
             }
             class B {
-                short getP() {
-                    return 2
-                }
+                short getP() { 3 }
             }
 
-            def foo(o) {
+            int foo(o) {
                 if (o instanceof A || o instanceof B) {
-                    return o.p
+                    return o.p.compareTo(2)
                 }
             }
-            assert foo(new A()) == 1
-            assert foo(new B()) == 2
+            assert foo(new A()) < 0
+            assert foo(new B()) > 0
         '''
     }
 

Reply via email to