From f0cefd5583e0242ffb8e344abed6172f94f00ba9 Mon Sep 17 00:00:00 2001 From: Stanislav Erokhin Date: Wed, 25 Nov 2015 16:49:56 +0300 Subject: [PATCH] Create hacks for magic annotations NoInfer, OnlyInputTypes and LowPriorityInOverloadResolution. --- .../calls/inference/ConstraintSystemImpl.kt | 29 +++++++++++++++++++ .../noInferAndLowPriority.kt | 15 ++++++++++ .../noInferAndLowPriority.txt | 5 ++++ .../onlyInputTypesAndLowPriority.kt | 25 ++++++++++++++++ .../onlyInputTypesAndLowPriority.txt | 7 +++++ .../DiagnosticsTestWithStdLibGenerated.java | 12 ++++++++ 6 files changed, 93 insertions(+) create mode 100644 compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/noInferAndLowPriority.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/noInferAndLowPriority.txt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndLowPriority.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndLowPriority.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt index 6d68013d10d..af764befc04 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt @@ -49,6 +49,35 @@ internal class ConstraintSystemImpl( override fun hasContradiction() = hasParameterConstraintError() || hasConflictingConstraints() || hasCannotCaptureTypesError() || hasTypeInferenceIncorporationError() + // hacks for library migration todo: remove its later + || hasTypeParameterWithUnsatisfiedOnlyInputTypesError() + + /** + * Hacks above are needed for the following example: + * + * @kotlin.jvm.JvmName("containsAny") + * @kotlin.internal.LowPriorityInOverloadResolution + * public operator fun Iterable.contains(element: T): Boolean + * + * public operator fun <@kotlin.internal.OnlyInputTypes T> Iterable.contains(element: T): Boolean + * + * fun test() = listOf(1).contains("") + * + * When we resolve call `contains`, we should choose candidate before we complete inference. + * Because of this we can't check OnlyInputTypes when we trying choose candidate. + * Now we do this check in this moment, but it is incorrect and we should remove it later. + * + * Call !satisfyInitialConstraints() in hasTypeInferenceIncorporationError() is needed for this example: + * @kotlin.jvm.JvmName("containsAny") + * @kotlin.internal.LowPriorityInOverloadResolution + * public operator fun Iterable.contains(element: T): Boolean + * + * public operator fun Iterable.contains(element: @kotlin.internal.NoInfer T) + * + * fun test() = listOf(1).contains("") + * + * It is also incorrect, because we can get additional constraints on T after we resolve call `contains`. + */ override fun hasViolatedUpperBound() = !isSuccessful() && filterConstraintsOut(TYPE_BOUND_POSITION).status.isSuccessful() diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/noInferAndLowPriority.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/noInferAndLowPriority.kt new file mode 100644 index 00000000000..8e25d532b80 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/noInferAndLowPriority.kt @@ -0,0 +1,15 @@ +//!DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +@kotlin.jvm.JvmName("containsAny") +@kotlin.internal.LowPriorityInOverloadResolution +public fun Iterable.contains1(element: T): Int = null!! + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +public fun Iterable.contains1(element: @kotlin.internal.NoInfer T): Boolean = null!! + + +fun test() { + val a: Int = listOf(1).contains1("") + val b: Boolean = listOf(1).contains1(1) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/noInferAndLowPriority.txt b/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/noInferAndLowPriority.txt new file mode 100644 index 00000000000..ee9ab940340 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/noInferAndLowPriority.txt @@ -0,0 +1,5 @@ +package + +public fun test(): kotlin.Unit +@kotlin.Suppress(names = {"INVISIBLE_MEMBER", "INVISIBLE_REFERENCE"}) @kotlin.jvm.JvmName(name = "containsAny") @kotlin.internal.LowPriorityInOverloadResolution() public fun kotlin.Iterable.contains1(/*0*/ element: T): kotlin.Int +@kotlin.Suppress(names = {"INVISIBLE_MEMBER", "INVISIBLE_REFERENCE"}) public fun kotlin.Iterable.contains1(/*0*/ element: T): kotlin.Boolean diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndLowPriority.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndLowPriority.kt new file mode 100644 index 00000000000..9219014ce94 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndLowPriority.kt @@ -0,0 +1,25 @@ +//!DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +@kotlin.jvm.JvmName("containsAny") +@kotlin.internal.LowPriorityInOverloadResolution +public fun Iterable.contains1(element: T): Int = null!! + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +public fun <@kotlin.internal.OnlyInputTypes T> Iterable.contains1(element: T): Boolean = null!! + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +@JvmName("getAny") +@kotlin.internal.LowPriorityInOverloadResolution +public fun Map.get1(key: Any?): Int = null!! + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +public fun <@kotlin.internal.OnlyInputTypes K, V> Map.get1(key: K): V? = null!! + +fun test(map: Map) { + val a: Int = listOf(1).contains1("") + val b: Boolean = listOf(1).contains1(1) + + val c: Int = map.get1("") + val d: String? = map.get1(1) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndLowPriority.txt b/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndLowPriority.txt new file mode 100644 index 00000000000..c5a1c0acecf --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndLowPriority.txt @@ -0,0 +1,7 @@ +package + +public fun test(/*0*/ map: kotlin.Map): kotlin.Unit +@kotlin.Suppress(names = {"INVISIBLE_MEMBER", "INVISIBLE_REFERENCE"}) @kotlin.jvm.JvmName(name = "containsAny") @kotlin.internal.LowPriorityInOverloadResolution() public fun kotlin.Iterable.contains1(/*0*/ element: T): kotlin.Int +@kotlin.Suppress(names = {"INVISIBLE_MEMBER", "INVISIBLE_REFERENCE"}) public fun kotlin.Iterable.contains1(/*0*/ element: T): kotlin.Boolean +@kotlin.Suppress(names = {"INVISIBLE_MEMBER", "INVISIBLE_REFERENCE"}) @kotlin.jvm.JvmName(name = "getAny") @kotlin.internal.LowPriorityInOverloadResolution() public fun kotlin.Map.get1(/*0*/ key: kotlin.Any?): kotlin.Int +@kotlin.Suppress(names = {"INVISIBLE_MEMBER", "INVISIBLE_REFERENCE"}) public fun kotlin.Map.get1(/*0*/ key: K): V? diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java index 153054f9fd1..59c7c0a7016 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java @@ -708,12 +708,24 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW doTest(fileName); } + @TestMetadata("noInferAndLowPriority.kt") + public void testNoInferAndLowPriority() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/noInferAndLowPriority.kt"); + doTest(fileName); + } + @TestMetadata("noInferAnnotation.kt") public void testNoInferAnnotation() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/noInferAnnotation.kt"); doTest(fileName); } + @TestMetadata("onlyInputTypesAndLowPriority.kt") + public void testOnlyInputTypesAndLowPriority() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndLowPriority.kt"); + doTest(fileName); + } + @TestMetadata("onlyInputTypesAnnotationWithPlatformTypes.kt") public void testOnlyInputTypesAnnotationWithPlatformTypes() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAnnotationWithPlatformTypes.kt");