Skip to content
Permalink
Browse files
GROOVY-10114: STC: diamond inference: handle ternary without target type
  • Loading branch information
eric-milles committed Mar 15, 2022
1 parent 2af61e8 commit 4869241faded5ef0d75636887840608055c9f76e
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 4 deletions.
@@ -4185,11 +4185,16 @@ && isTypeSource(expr, enclosingMethod)) {
targetType = enclosingMethod.getReturnType();
}

if (expr instanceof ConstructorCallExpression) { // GROOVY-9972, GROOVY-9983
// GROOVY-10114: type parameter(s) could be inferred from call arguments
if (targetType == null) targetType = sourceType.getPlainNodeReference();
inferDiamondType((ConstructorCallExpression) expr, targetType);
return sourceType;
}

if (targetType == null) return sourceType;

if (expr instanceof ConstructorCallExpression) {
inferDiamondType((ConstructorCallExpression) expr, targetType);
} else if (!isPrimitiveType(getUnwrapper(targetType))
if (!isPrimitiveType(getUnwrapper(targetType))
&& !isObjectType(targetType) && missesGenericsTypes(sourceType)) {
// unchecked assignment with ternary/elvis, like "List<T> list = listOfT ?: []"
// the inferred type is the RHS type "completed" with generics information from LHS
@@ -989,7 +989,8 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
C.m(new A<>(new B()))
C.m(new A<>(new E()))
C.m(flag ? new A<>(new B()) : new A<>(new B()))
C.m(flag ? new A<>(new B()) : new A<>(new E())) // Cannot call m(A<B>) with arguments [A<? extends B>]
C.m(flag ? new A<>(new B()) : new A<>((B)null))
C.m(flag ? new A<>(new B()) : new A<>((B)new E())) // Cannot call m(A<B>) with arguments [A<? extends B>]
'''

shouldFailWithMessages types + '''
@@ -1005,6 +1006,25 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
'Cannot call C#m(A<B>) with arguments [A<? extends java.lang.Object>]'
}

// GROOVY-10114
void testDiamondInferrenceFromConstructor14a() {
assertScript '''
@groovy.transform.TupleConstructor(defaults=false)
class A<T> {
T p
}
class B {
Character m() {
(Character) '!'
}
}
(false ? new A<B>(new B()) : new A<>(new B())).p.m()
(false ? new A< >(new B()) : new A<>(new B())).p.m()
def a = (true ? new A<>(new B()) : new A<>(new B()))
assert a.p.m() == (char)'!'
'''
}

// GROOVY-9995
void testDiamondInferrenceFromConstructor15() {
[

0 comments on commit 4869241

Please sign in to comment.