From 9aef6910abf344478aa87a57d9d13c3a1abfcad5 Mon Sep 17 00:00:00 2001 From: Victor Petukhov Date: Wed, 25 May 2022 11:00:51 +0200 Subject: [PATCH] [FE 1.0] Check callable reference return type safety during resolution ^KT-51844 ^KT-52503 Fixed --- ...CompilerTestFE10TestdataTestGenerated.java | 6 ++++ ...irOldFrontendDiagnosticsTestGenerated.java | 6 ++++ ...DiagnosticsWithLightTreeTestGenerated.java | 6 ++++ .../FirBlackBoxCodegenTestGenerated.java | 6 ++++ ...enteringLazyValueComputationException.java | 3 +- .../CallableReferencesCandidateFactory.kt | 10 +++++- .../codegen/box/callableReference/kt51844.kt | 15 +++++++++ .../tests/callableReference/kt52503.kt | 16 ++++++++++ .../tests/callableReference/kt52503.txt | 19 ++++++++++++ .../tests/platformTypes/kt50877.fir.kt | 31 ------------------- .../tests/platformTypes/kt50877.kt | 1 + .../test/runners/DiagnosticTestGenerated.java | 6 ++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++++ .../IrBlackBoxCodegenTestGenerated.java | 6 ++++ .../LightAnalysisModeTestGenerated.java | 5 +++ .../LazyWrappedTypeComputationException.kt | 8 +++++ .../js/test/JsCodegenBoxTestGenerated.java | 6 ++++ .../test/ir/IrJsCodegenBoxTestGenerated.java | 6 ++++ .../IrCodegenBoxWasmTestGenerated.java | 5 +++ .../NativeCodegenBoxTestGenerated.java | 6 ++++ 20 files changed, 140 insertions(+), 33 deletions(-) create mode 100644 compiler/testData/codegen/box/callableReference/kt51844.kt create mode 100644 compiler/testData/diagnostics/tests/callableReference/kt52503.kt create mode 100644 compiler/testData/diagnostics/tests/callableReference/kt52503.txt delete mode 100644 compiler/testData/diagnostics/tests/platformTypes/kt50877.fir.kt create mode 100644 core/descriptors/src/org/jetbrains/kotlin/types/error/LazyWrappedTypeComputationException.kt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 05588767f4145..3c8fb41d3d0e5 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -2814,6 +2814,12 @@ public void testKt49038() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/kt49038.kt"); } + @Test + @TestMetadata("kt52503.kt") + public void testKt52503() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/kt52503.kt"); + } + @Test @TestMetadata("kt7430_wrongClassOnLHS.kt") public void testKt7430_wrongClassOnLHS() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index ceb4d159ce0e9..e525cc6cb6886 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -2814,6 +2814,12 @@ public void testKt49038() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/kt49038.kt"); } + @Test + @TestMetadata("kt52503.kt") + public void testKt52503() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/kt52503.kt"); + } + @Test @TestMetadata("kt7430_wrongClassOnLHS.kt") public void testKt7430_wrongClassOnLHS() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index a25e1beecc5be..311449478d09b 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -2814,6 +2814,12 @@ public void testKt49038() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/kt49038.kt"); } + @Test + @TestMetadata("kt52503.kt") + public void testKt52503() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/kt52503.kt"); + } + @Test @TestMetadata("kt7430_wrongClassOnLHS.kt") public void testKt7430_wrongClassOnLHS() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 79ce823917785..830bd5b5c9ec7 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -3129,6 +3129,12 @@ public void testKt50172() throws Exception { runTest("compiler/testData/codegen/box/callableReference/kt50172.kt"); } + @Test + @TestMetadata("kt51844.kt") + public void testKt51844() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/kt51844.kt"); + } + @Test @TestMetadata("nested.kt") public void testNested() throws Exception { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/util/ReenteringLazyValueComputationException.java b/compiler/frontend/src/org/jetbrains/kotlin/util/ReenteringLazyValueComputationException.java index 5be947c2021a1..ed607710a4573 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/util/ReenteringLazyValueComputationException.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/util/ReenteringLazyValueComputationException.java @@ -19,8 +19,9 @@ import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.types.error.LazyWrappedTypeComputationException; -public class ReenteringLazyValueComputationException extends RuntimeException { +public class ReenteringLazyValueComputationException extends LazyWrappedTypeComputationException { public ReenteringLazyValueComputationException() { } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/CallableReferencesCandidateFactory.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/CallableReferencesCandidateFactory.kt index ba69a1ef2b7a6..92a83736f1348 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/CallableReferencesCandidateFactory.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/CallableReferencesCandidateFactory.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.error.ErrorScopeKind import org.jetbrains.kotlin.types.error.ErrorUtils import org.jetbrains.kotlin.types.error.ErrorTypeKind +import org.jetbrains.kotlin.types.error.LazyWrappedTypeComputationException import org.jetbrains.kotlin.types.expressions.CoercionStrategy import org.jetbrains.kotlin.types.typeUtil.isUnit import org.jetbrains.kotlin.utils.SmartList @@ -239,8 +240,15 @@ class CallableReferencesCandidateFactory( // lower(Unit!) = Unit val returnExpectedType = inputOutputTypes.outputType + fun isReturnTypeNonUnitSafe(): Boolean = + try { + descriptor.returnType?.isUnit() == false + } catch (e: LazyWrappedTypeComputationException) { + false + } + val coercion = - if (returnExpectedType.isUnit() && descriptor.returnType?.isUnit() == false) + if (returnExpectedType.isUnit() && isReturnTypeNonUnitSafe()) CoercionStrategy.COERCION_TO_UNIT else CoercionStrategy.NO_COERCION diff --git a/compiler/testData/codegen/box/callableReference/kt51844.kt b/compiler/testData/codegen/box/callableReference/kt51844.kt new file mode 100644 index 0000000000000..83712bb4021a1 --- /dev/null +++ b/compiler/testData/codegen/box/callableReference/kt51844.kt @@ -0,0 +1,15 @@ +// WITH_STDLIB + +abstract class Foo { + abstract fun contains(x: Int); +} + +// ERROR: Type checking has run into a recursive problem. Easiest workaround: specify types of your declarations explicitly +fun Foo.contains(vararg xs: Int) = xs.forEach(this::contains) + +fun box(): String { + object : Foo() { + override fun contains(x: Int) {} + }.contains(1) + return "OK" +} diff --git a/compiler/testData/diagnostics/tests/callableReference/kt52503.kt b/compiler/testData/diagnostics/tests/callableReference/kt52503.kt new file mode 100644 index 0000000000000..4c12774c8c727 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/kt52503.kt @@ -0,0 +1,16 @@ +// FIR_IDENTICAL +// WITH_STDLIB + +abstract class Foo + +object A { + fun Foo.contains(vararg xs: Int) = // 1 + xs.forEach(this::contains) // resolved to (2) in 1.7.0-RC, should be error "Type checking has run into a recursive problem" +} + +fun Any.contains(vararg xs: Int) {} // 2 + +fun box(): String { + object : Foo() {}.contains(1) + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/callableReference/kt52503.txt b/compiler/testData/diagnostics/tests/callableReference/kt52503.txt new file mode 100644 index 0000000000000..59a01895ac5cd --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/kt52503.txt @@ -0,0 +1,19 @@ +package + +public fun box(): kotlin.String +public fun kotlin.Any.contains(/*0*/ vararg xs: kotlin.Int /*kotlin.IntArray*/): kotlin.Unit + +public object A { + private constructor A() + 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 + public final fun Foo.contains(/*0*/ vararg xs: kotlin.Int /*kotlin.IntArray*/): kotlin.Unit +} + +public abstract class Foo { + public constructor Foo() + 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 +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/kt50877.fir.kt b/compiler/testData/diagnostics/tests/platformTypes/kt50877.fir.kt deleted file mode 100644 index 99d5b00751037..0000000000000 --- a/compiler/testData/diagnostics/tests/platformTypes/kt50877.fir.kt +++ /dev/null @@ -1,31 +0,0 @@ -// FULL_JDK -// WITH_STDLIB - -// FILE: Schematic.kt -class Schematic { - var name: String? = null - - var error: String? = null - - override fun toString(): String { - return name!! - } -} - -// FILE: SortedListModel.java -import java.util.Comparator; - -public class SortedListModel { - public SortedListModel(Comparator comparator) { - } -} - - -// FILE: main.kt -val model = SortedListModel(Comparator.comparing { b1: Schematic -> - when { - b1.error != null -> 2 - b1.name!!.contains(":") -> 1 - else -> 0 - } -}.thenComparing { b1: Schematic -> b1.name!! }) \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/platformTypes/kt50877.kt b/compiler/testData/diagnostics/tests/platformTypes/kt50877.kt index 99d5b00751037..1b57f849afd06 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/kt50877.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/kt50877.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // FULL_JDK // WITH_STDLIB diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 1dc93e33c849b..614e4e99be2b2 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -2820,6 +2820,12 @@ public void testKt49038() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/kt49038.kt"); } + @Test + @TestMetadata("kt52503.kt") + public void testKt52503() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/kt52503.kt"); + } + @Test @TestMetadata("kt7430_wrongClassOnLHS.kt") public void testKt7430_wrongClassOnLHS() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 00db29c22567d..7497764b71dfb 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -3033,6 +3033,12 @@ public void testKt50172() throws Exception { runTest("compiler/testData/codegen/box/callableReference/kt50172.kt"); } + @Test + @TestMetadata("kt51844.kt") + public void testKt51844() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/kt51844.kt"); + } + @Test @TestMetadata("nested.kt") public void testNested() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index a0808c6543b94..b817f4119ced2 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -3129,6 +3129,12 @@ public void testKt50172() throws Exception { runTest("compiler/testData/codegen/box/callableReference/kt50172.kt"); } + @Test + @TestMetadata("kt51844.kt") + public void testKt51844() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/kt51844.kt"); + } + @Test @TestMetadata("nested.kt") public void testNested() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 894e71a6d1583..4dd95575857a5 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -2658,6 +2658,11 @@ public void testKt50172() throws Exception { runTest("compiler/testData/codegen/box/callableReference/kt50172.kt"); } + @TestMetadata("kt51844.kt") + public void testKt51844() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/kt51844.kt"); + } + @TestMetadata("nested.kt") public void testNested() throws Exception { runTest("compiler/testData/codegen/box/callableReference/nested.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/error/LazyWrappedTypeComputationException.kt b/core/descriptors/src/org/jetbrains/kotlin/types/error/LazyWrappedTypeComputationException.kt new file mode 100644 index 0000000000000..44d0ee1f6dad3 --- /dev/null +++ b/core/descriptors/src/org/jetbrains/kotlin/types/error/LazyWrappedTypeComputationException.kt @@ -0,0 +1,8 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.types.error + +abstract class LazyWrappedTypeComputationException : RuntimeException() diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java index 35dc84264507f..5206c5520959d 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java @@ -1983,6 +1983,12 @@ public void testKt50172() throws Exception { runTest("compiler/testData/codegen/box/callableReference/kt50172.kt"); } + @Test + @TestMetadata("kt51844.kt") + public void testKt51844() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/kt51844.kt"); + } + @Test @TestMetadata("nested.kt") public void testNested() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java index 12b8b1cba11ae..b17f4de25cdb5 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java @@ -2025,6 +2025,12 @@ public void testKt50172() throws Exception { runTest("compiler/testData/codegen/box/callableReference/kt50172.kt"); } + @Test + @TestMetadata("kt51844.kt") + public void testKt51844() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/kt51844.kt"); + } + @Test @TestMetadata("nested.kt") public void testNested() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index 570aae315b85a..5917b91d98450 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -1808,6 +1808,11 @@ public void testKt50172() throws Exception { runTest("compiler/testData/codegen/box/callableReference/kt50172.kt"); } + @TestMetadata("kt51844.kt") + public void testKt51844() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/kt51844.kt"); + } + @TestMetadata("nested.kt") public void testNested() throws Exception { runTest("compiler/testData/codegen/box/callableReference/nested.kt"); diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java index 9ccdb4381105a..df8e562f1ed2b 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java @@ -2077,6 +2077,12 @@ public void testKt50172() throws Exception { runTest("compiler/testData/codegen/box/callableReference/kt50172.kt"); } + @Test + @TestMetadata("kt51844.kt") + public void testKt51844() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/kt51844.kt"); + } + @Test @TestMetadata("nested.kt") public void testNested() throws Exception {