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/05/16 19:32:26 UTC
[groovy] 03/03: GROOVY-10343: STC: resolve type parameter bounded by a type parameter
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 7f3c77d73cdd90d1cffa12e2281b3e5de7853efa
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon May 16 11:58:56 2022 -0500
GROOVY-10343: STC: resolve type parameter bounded by a type parameter
---
.../transform/stc/StaticTypeCheckingSupport.java | 28 ++++++++++++----------
.../groovy/transform/stc/GenericsSTCTest.groovy | 17 +++++++++++++
2 files changed, 32 insertions(+), 13 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 ebbf3945c2..2fdbb432b0 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -1606,22 +1606,24 @@ public abstract class StaticTypeCheckingSupport {
}
}
- private static ClassNode extractType(final GenericsType gt) {
+ private static ClassNode extractType(GenericsType gt) {
+ ClassNode cn;
if (!gt.isPlaceholder()) {
- return gt.getType();
- }
- // 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 = gt.getType().redirect();
- if (gt.getType().getGenericsTypes() != null) {
- GenericsType realGt = gt.getType().getGenericsTypes()[0];
- if (realGt.getLowerBound() != null) {
- replacementType = realGt.getLowerBound();
- } else if (realGt.getUpperBounds() != null && realGt.getUpperBounds().length > 0) {
- replacementType = realGt.getUpperBounds()[0];
+ cn = gt.getType();
+ } else {
+ // discard the placeholder
+ cn = gt.getType().redirect();
+
+ if (gt.getType().getGenericsTypes() != null)
+ gt = gt.getType().getGenericsTypes()[0];
+
+ if (gt.getLowerBound() != null) {
+ cn = gt.getLowerBound();
+ } else if (asBoolean(gt.getUpperBounds())) {
+ cn = gt.getUpperBounds()[0];
}
}
- return replacementType;
+ return cn;
}
private static boolean equalIncludingGenerics(final GenericsType orig, final GenericsType copy) {
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index 2622f7303a..ef74410951 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -1219,6 +1219,23 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
'''
}
+ // GROOVY-10343
+ void testDiamondInferrenceFromConstructor27() {
+ assertScript '''
+ class C<T1, T2 extends T1> {
+ T1 p
+ C(T1 p) { this.p = p }
+ T2 m() { return null }
+ }
+ void test(Integer x) {
+ def c = new C<>(x) // type witness for T1 can also help bound T2
+ def y = c.m()
+ Integer z = y // Cannot assign value of type Object to variable of type Integer
+ }
+ test(1234)
+ '''
+ }
+
// GROOVY-10280
void testTypeArgumentPropagation() {
assertScript '''