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
commit dc14af29347912bcbf89fa5dbff303b40e5bf01f Author: Eric Milles <[email protected]> AuthorDate: Tue Sep 13 12:06:20 2022 -0500 GROOVY-10315, GROOVY-10317: STC: merge multiple witnesses for type param of method --- .../transform/stc/StaticTypeCheckingSupport.java | 23 +++++++++++++++------- .../groovy/transform/stc/GenericsSTCTest.groovy | 21 +++++++++++++++++++- 2 files changed, 36 insertions(+), 8 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 3bcb9c1062..3bd4db3dd4 100644 --- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java +++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java @@ -468,11 +468,7 @@ public abstract class StaticTypeCheckingSupport { } return true; } - if (type.isDerivedFrom(CLOSURE_TYPE) && isSAMType(toBeAssignedTo)) { - return true; - } - - return false; + return (type.isDerivedFrom(CLOSURE_TYPE) && isSAMType(toBeAssignedTo)); } static boolean isVargs(final Parameter[] parameters) { @@ -644,6 +640,11 @@ public abstract class StaticTypeCheckingSupport { return checkCompatibleAssignmentTypes(left, right, rightExpression, true); } + /** + * Everything that can be done by {@code castToType} should be allowed for assignment. + * + * @see org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation#castToType(Object,Class) + */ public static boolean checkCompatibleAssignmentTypes(final ClassNode left, final ClassNode right, final Expression rightExpression, final boolean allowConstructorCoercion) { if (!isPrimitiveType(left) && isNullConstant(rightExpression)) { return true; @@ -823,7 +824,7 @@ public abstract class StaticTypeCheckingSupport { return !Double.valueOf(val).equals(number); } default: // double - return false; // no possible loose here + return false; // no possible loss here } } return true; // possible loss of precision @@ -885,7 +886,7 @@ public abstract class StaticTypeCheckingSupport { if (type.isArray() && superOrInterface.isArray()) { return implementsInterfaceOrIsSubclassOf(type.getComponentType(), superOrInterface.getComponentType()); } - if (GROOVY_OBJECT_TYPE.equals(superOrInterface) && !type.isInterface() && isBeingCompiled(type)) { + if (superOrInterface.equals(GROOVY_OBJECT_TYPE) && !type.isInterface() && isBeingCompiled(type)) { return true; } return false; @@ -1603,6 +1604,14 @@ public abstract class StaticTypeCheckingSupport { GenericsTypeName name = new GenericsTypeName(oldValue.getName()); GenericsType newValue = connections.get(name); // find "V" in T=V if (newValue == oldValue) continue; + if (newValue == null) { + newValue = connections.get(entry.getKey()); + if (newValue != null) { // GROOVY-10315, GROOVY-10317 + ClassNode o = GenericsUtils.makeClassSafe0(CLASS_Type, oldValue), + n = GenericsUtils.makeClassSafe0(CLASS_Type, newValue); + newValue = WideningCategories.lowestUpperBound(o,n).getGenericsTypes()[0]; + } + } if (newValue == null) { entry.setValue(newValue = applyGenericsContext(connections, oldValue)); checkForMorePlaceholders = checkForMorePlaceholders || !equalIncludingGenerics(oldValue, newValue); diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy index da8b9dba83..2dce5be83f 100644 --- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy +++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy @@ -2392,7 +2392,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase { // GROOVY-10315 void testShouldUseMethodGenericType14() { - for (args in ['m2(), c.m()'/*, 'c.m(), m2()'*/]) { + for (args in ['m2(), c.m()', 'c.m(), m2()']) { assertScript """ class C<T> { def T m() { @@ -2410,6 +2410,25 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase { } } + // GROOVY-10317 + void testShouldUseMethodGenericType14a() { + assertScript ''' + class B { + def <X> X m() { + } + } + class C<Y,Z> { + void p(Y y) { + } + void test() { + def b = new B() + (new C<Z,Z>()).p(b.m()) + } + } + new C().test() + ''' + } + // GROOVY-10364 void testShouldUseMethodGenericType15() { assertScript '''
