diff --git a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java index 60e2562e6e..989e9e93c7 100644 --- a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java +++ b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java @@ -5138,6 +5138,26 @@ public void testTypeChecked10357() { runConformTest(sources, "1"); } + @Test + public void testTypeChecked10367() { + //@formatter:off + String[] sources = { + "Main.groovy", + "@groovy.transform.TupleConstructor(defaults=false)\n" + + "class C {\n" + // works without Y + " X x\n" + + "}\n" + + "@groovy.transform.TypeChecked\n" + + "def void test(Z z) {\n" + + " z = new C<>(z).x\n" + // Cannot assign value of type Object to variable of type Z + "}\n" + + "test(null)\n", + }; + //@formatter:on + + runConformTest(sources); + } + @Test public void testTypeChecked10368() { for (String bounds : new String[] {"T", "T extends Number", "T extends Object"}) { diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java index ba229f99e5..fcc8706a9c 100644 --- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -1204,7 +1204,7 @@ protected void inferDiamondType(final ConstructorCallExpression cce, final Class // check if constructor call expression makes use of the diamond operator if (cceType.getGenericsTypes() != null && cceType.getGenericsTypes().length == 0) { ArgumentListExpression argumentListExpression = InvocationWriter.makeArgumentList(cce.getArguments()); - /* GRECLIPSE edit -- GROOVY-9948, GROOVY-9983, GROOVY-10291, GROOVY-10368, et al. + /* GRECLIPSE edit -- GROOVY-9948, GROOVY-9983, GROOVY-10291, GROOVY-10367, GROOVY-10368, et al. if (argumentListExpression.getExpressions().isEmpty()) { adjustGenerics(lType, cceType); } else { @@ -1221,9 +1221,10 @@ protected void inferDiamondType(final ConstructorCallExpression cce, final Class ClassNode type = GenericsUtils.parameterizeType(cceType, cceType); type = inferReturnTypeGenerics(type, constructor, argumentListExpression); // process target as additional type witness, if ... - if (type.toString(false).indexOf('#') > 0 // unresolved generics - // GROOVY-6232, GROOVY-9956: cce not assignment compatible - || checkCompatibleAssignmentTypes(lType, type, cce) && !GenericsUtils.buildWildcardType(lType).isCompatibleWith(type)) { + if (lType.getGenericsTypes() != null // has generics + && (type.toString(false).indexOf('#') > 0 // unresolved generics + // GROOVY-6232, GROOVY-9956, etc.: cce not assignment compatible + || checkCompatibleAssignmentTypes(lType, type, cce) && !GenericsUtils.buildWildcardType(lType).isCompatibleWith(type))) { // allow covariance of each type parameter, but maintain semantics for nested generics ClassNode pType = GenericsUtils.parameterizeType(lType, type); diff --git a/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java index 7165ff1022..50182fba24 100644 --- a/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -1127,7 +1127,7 @@ protected void inferDiamondType(final ConstructorCallExpression cce, final Class ClassNode cceType = cce.getType(), inferredType = lType; // check if constructor call expression makes use of the diamond operator if (cceType.getGenericsTypes() != null && cceType.getGenericsTypes().length == 0) { - /* GRECLIPSE edit -- GROOVY-9948, GROOVY-9983, GROOVY-10291, GROOVY-10368, et al. + /* GRECLIPSE edit -- GROOVY-9948, GROOVY-9983, GROOVY-10291, GROOVY-10367, GROOVY-10368, et al. ArgumentListExpression argumentListExpression = InvocationWriter.makeArgumentList(cce.getArguments()); if (argumentListExpression.getExpressions().isEmpty()) { adjustGenerics(lType, cceType); @@ -1146,9 +1146,10 @@ protected void inferDiamondType(final ConstructorCallExpression cce, final Class ClassNode type = GenericsUtils.parameterizeType(cceType, cceType); type = inferReturnTypeGenerics(type, constructor, argumentList); // process target as additional type witness, if ... - if (type.toString(false).indexOf('#') > 0 // unresolved generics - // GROOVY-6232, GROOVY-9956: cce not assignment compatible - || checkCompatibleAssignmentTypes(lType, type, cce) && !GenericsUtils.buildWildcardType(lType).isCompatibleWith(type)) { + if (lType.getGenericsTypes() != null // has generics + && (type.toString(false).indexOf('#') > 0 // unresolved generics + // GROOVY-6232, GROOVY-9956, etc.: cce not assignment compatible + || checkCompatibleAssignmentTypes(lType, type, cce) && !GenericsUtils.buildWildcardType(lType).isCompatibleWith(type))) { // allow covariance of each type parameter, but maintain semantics for nested generics ClassNode pType = GenericsUtils.parameterizeType(lType, type); diff --git a/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java index 74339ca1b0..ff3475a833 100644 --- a/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -1111,9 +1111,10 @@ protected void inferDiamondType(final ConstructorCallExpression cce, final Class if (!argumentList.getExpressions().isEmpty() && constructor != null) { ClassNode type = GenericsUtils.parameterizeType(cceType, cceType); type = inferReturnTypeGenerics(type, constructor, argumentList); - if (type.toString(false).indexOf('#') > 0 // GROOVY-9983, GROOVY-10291, GROOVY-10368 + if (lType.getGenericsTypes() != null // GROOVY-10367: nothing to inspect + && (type.toString(false).indexOf('#') > 0 // GROOVY-9983, GROOVY-10291, GROOVY-10368: unresolved generic // GROOVY-6232, GROOVY-9956: if cce not assignment compatible, process target as additional type witness - || checkCompatibleAssignmentTypes(lType, type, cce) && !GenericsUtils.buildWildcardType(lType).isCompatibleWith(type)) { + || checkCompatibleAssignmentTypes(lType, type, cce) && !GenericsUtils.buildWildcardType(lType).isCompatibleWith(type))) { // allow covariance of each type parameter, but maintain semantics for nested generics ClassNode pType = GenericsUtils.parameterizeType(lType, type);