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/11/19 15:49:35 UTC
[groovy] branch GROOVY_3_0_X updated: GROOVY-10847: STC: `T t = new C<>()` where `T` extends 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
The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push:
new 511f95476e GROOVY-10847: STC: `T t = new C<>()` where `T` extends a type parameter
511f95476e is described below
commit 511f95476ed06bd3665218ae5f704726282dabda
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Nov 19 08:19:39 2022 -0600
GROOVY-10847: STC: `T t = new C<>()` where `T` extends a type parameter
---
.../transform/stc/StaticTypeCheckingVisitor.java | 5 +-
.../groovy/transform/stc/GenericsSTCTest.groovy | 122 +++++++++++++++++++++
2 files changed, 125 insertions(+), 2 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 299774bd39..4747f30576 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -1101,9 +1101,10 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
}
inferredType = type;
}
- if (inferredType.isGenericsPlaceHolder()) // GROOVY-10344: "T t = new C<>()"
+ // GROOVY-10344, GROOVY-10847: "T t = new C<>()" where "T" may extend another type parameter
+ while (inferredType.isGenericsPlaceHolder() && asBoolean(inferredType.getGenericsTypes())) {
inferredType = getCombinedBoundType(inferredType.getGenericsTypes()[0]);
-
+ }
adjustGenerics(inferredType, cceType);
storeType(cce, cceType);
}
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index 392c40d85d..1a6c455ae0 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -1537,6 +1537,128 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
'''
}
+ // GROOVY-10699
+ @NotYetImplemented
+ void testDiamondInferrenceFromConstructor33() {
+ assertScript '''
+ class A<T> {
+ A(B<T> b_of_t) {
+ }
+ }
+ class B<T> {
+ B(T t) {
+ }
+ }
+
+ @ASTTest(phase=INSTRUCTION_SELECTION, value={
+ def type = node.getNodeMetaData(INFERRED_TYPE)
+ assert type.toString(false) == 'A<java.lang.String>'
+ })
+ def x = new A<>(new B<>('str'))
+ '''
+
+ assertScript '''import java.util.function.Consumer
+ class C<T> {
+ C(Consumer<T> consumer_of_t) {
+ consumer_of_t.accept(null)
+ }
+ }
+
+ @ASTTest(phase=INSTRUCTION_SELECTION, value={
+ def type = node.getNodeMetaData(INFERRED_TYPE)
+ assert type.toString(false) == 'C<java.lang.String>'
+ })
+ def y = new C<>((String s) -> { print(s); }) // error: Expected type Object for lambda parameter: s
+ '''
+
+ assertScript '''import java.util.function.Supplier
+ class D<T> {
+ D(Supplier<T> supplier_of_t) {
+ T t = supplier_of_t.get()
+ }
+ }
+
+ @ASTTest(phase=INSTRUCTION_SELECTION, value={
+ def type = node.getNodeMetaData(INFERRED_TYPE)
+ assert type.toString(false) == 'D<java.lang.String>'
+ })
+ def z = new D<>(() -> 'str')
+ '''
+ }
+
+ // GROOVY-10698
+ @NotYetImplemented
+ void testDiamondInferrenceFromConstructor34() {
+ assertScript '''
+ class A<T> {
+ A(T t, B<T> b_of_t) {
+ }
+ }
+ class B<U> {
+ }
+
+ @ASTTest(phase=INSTRUCTION_SELECTION, value={
+ def type = node.getNodeMetaData(INFERRED_TYPE)
+ assert type.toString(false) == 'A<java.lang.String>'
+ })
+ def x = new A<>('witness', new B<>()) // Cannot call A#<init>(Object,B<Object>) with arguments [String, B<T>]
+ '''
+ }
+
+ // GROOVY-10847
+ void testDiamondInferrenceFromConstructor35() {
+ assertScript '''
+ class A<T, U> {
+ }
+ class B {
+ def <X extends A<Character, Boolean>, Y extends X> Object m(X x, Y y) {
+ }
+ }
+
+ @ASTTest(phase=INSTRUCTION_SELECTION, value={
+ def type = node.rightExpression.arguments[1].getNodeMetaData(INFERRED_TYPE)
+ assert type.toString(false) == 'A <java.lang.Character, java.lang.Boolean>'
+ })
+ def c = new B().m(null, new A<>())
+ '''
+ }
+
+ // GROOVY-10674
+ @NotYetImplemented
+ void testDiamondInferrenceFromConstructor36() {
+ assertScript '''
+ class Foo<BB extends Bar<Byte>, X extends BB> {
+ X x
+ Foo(X x) {
+ this.x = x
+ }
+ }
+ class Bar<T extends Number> {
+ }
+
+ class Baz {
+ static Foo<Bar<Byte>, ? super Bar<Byte>> foo = new Foo<>(new Bar<>())
+ }
+ new Baz()
+ '''
+
+ assertScript '''
+ class Foo<BBQ extends Bar<Byte, ? extends Byte>, X extends BBQ> {
+ X x
+ Foo(X x) {
+ this.x = x
+ }
+ }
+ class Bar<T extends Number, S extends T> {
+ }
+
+ class Baz {
+ Foo<Bar<Byte,Byte>, ? super Bar<Byte,Byte>> foo = new Foo<>(new Bar<>())
+ }
+ new Baz()
+ '''
+ }
+
// GROOVY-10280
void testTypeArgumentPropagation() {
assertScript '''