From 6e24b0f89d3906f8173301b1c8a0cf30415f3d52 Mon Sep 17 00:00:00 2001 From: Stanislav Erokhin Date: Fri, 7 Apr 2017 15:32:37 +0300 Subject: [PATCH] [NI] Approximate captured types when we resolve type variable TO_SUPER. --- .../inference/components/ResultTypeResolver.kt | 5 +++-- .../tests/inference/flexibleTypesAsUpperBound.kt | 13 +++++++++++++ .../tests/inference/flexibleTypesAsUpperBound.txt | 13 +++++++++++++ .../nullableTypeArgumentWithNotNullUpperBound.kt | 11 +++++++++++ .../nullableTypeArgumentWithNotNullUpperBound.txt | 5 +++++ .../kotlin/checkers/DiagnosticsTestGenerated.java | 12 ++++++++++++ 6 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/inference/flexibleTypesAsUpperBound.kt create mode 100644 compiler/testData/diagnostics/tests/inference/flexibleTypesAsUpperBound.txt create mode 100644 compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.kt create mode 100644 compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.txt diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt index 923320ed77e..a90465c8794 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt @@ -58,7 +58,6 @@ class ResultTypeResolver( * * To fix this problem when we fix variable, we will approximate captured types before fixation. * - * todo: may be for TO_SUPER direction we should do the same */ return typeApproximator.approximateToSuperType(commonSupertype, TypeApproximatorConfiguration.CapturedTypesApproximation) ?: commonSupertype @@ -68,7 +67,9 @@ class ResultTypeResolver( // direction == TO_SUPER or there is no LOWER bounds val upperConstraints = variableWithConstraints.constraints.filter { it.kind == ConstraintKind.UPPER && c.isProperType(it.type) } if (upperConstraints.isNotEmpty()) { - return intersectTypes(upperConstraints.map { it.type }) + val upperType = intersectTypes(upperConstraints.map { it.type }) + + return typeApproximator.approximateToSubType(upperType, TypeApproximatorConfiguration.CapturedTypesApproximation) ?: upperType } return null diff --git a/compiler/testData/diagnostics/tests/inference/flexibleTypesAsUpperBound.kt b/compiler/testData/diagnostics/tests/inference/flexibleTypesAsUpperBound.kt new file mode 100644 index 00000000000..dc0f951ef84 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/flexibleTypesAsUpperBound.kt @@ -0,0 +1,13 @@ +// FILE: 1.kt +fun Array.plus(): Array { + val result = Arrays.copyOf(this, 3) + // result type is Array<(out) (S&Any)!>! + return result +} + +// FILE: Arrays.java +public class Arrays { + public static T[] copyOf(T[] original, int newLength) { + return (T[]) null; + } +} diff --git a/compiler/testData/diagnostics/tests/inference/flexibleTypesAsUpperBound.txt b/compiler/testData/diagnostics/tests/inference/flexibleTypesAsUpperBound.txt new file mode 100644 index 00000000000..8dd66e73d38 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/flexibleTypesAsUpperBound.txt @@ -0,0 +1,13 @@ +package + +public fun kotlin.Array.plus(): kotlin.Array + +public open class Arrays { + public constructor Arrays() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public open fun copyOf(/*0*/ original: kotlin.Array<(out) T!>!, /*1*/ newLength: kotlin.Int): kotlin.Array<(out) T!>! +} diff --git a/compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.kt b/compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.kt new file mode 100644 index 00000000000..67da957de5c --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.kt @@ -0,0 +1,11 @@ +fun foo(x: Array, y: Array) { + val xo = outA(x) + val yo = inA(y) + + var f: Array = xo + f = yo +} + + +fun outA(x: Array): Array = TODO() +fun inA(x: Array): Array = TODO() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.txt b/compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.txt new file mode 100644 index 00000000000..ef7cfe651be --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.txt @@ -0,0 +1,5 @@ +package + +public fun foo(/*0*/ x: kotlin.Array, /*1*/ y: kotlin.Array): kotlin.Unit +public fun inA(/*0*/ x: kotlin.Array): kotlin.Array +public fun outA(/*0*/ x: kotlin.Array): kotlin.Array diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index ff9db612d00..69341ee0e7c 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -10048,6 +10048,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("flexibleTypesAsUpperBound.kt") + public void testFlexibleTypesAsUpperBound() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/flexibleTypesAsUpperBound.kt"); + doTest(fileName); + } + @TestMetadata("functionPlaceholderError.kt") public void testFunctionPlaceholderError() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/functionPlaceholderError.kt"); @@ -10162,6 +10168,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("nullableTypeArgumentWithNotNullUpperBound.kt") + public void testNullableTypeArgumentWithNotNullUpperBound() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.kt"); + doTest(fileName); + } + @TestMetadata("nullableUpperBound.kt") public void testNullableUpperBound() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/nullableUpperBound.kt");