From 74118930b48fa115659612cf0ec26796e2aed934 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Wed, 10 Mar 2021 17:50:10 +0300 Subject: [PATCH] [FE] Don't fail with exception if ESVisitor tries to visit ESLambda #KT-45243 Fixed --- ...irOldFrontendDiagnosticsTestGenerated.java | 6 ++++++ .../kotlin/contracts/ESDataFlowValue.kt | 4 ++-- .../contracts/model/ESExpressionVisitor.kt | 5 ++++- .../contracts/model/visitors/InfoCollector.kt | 7 +++---- .../contracts/model/visitors/Reducer.kt | 8 ++++++-- .../contracts/model/visitors/Substitutor.kt | 11 +++++------ .../contracts/fromStdlib/kt45243.fir.kt | 19 +++++++++++++++++++ .../contracts/fromStdlib/kt45243.kt | 19 +++++++++++++++++++ .../contracts/fromStdlib/kt45243.txt | 8 ++++++++ .../test/runners/DiagnosticTestGenerated.java | 6 ++++++ 10 files changed, 78 insertions(+), 15 deletions(-) create mode 100644 compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/kt45243.fir.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/kt45243.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/kt45243.txt 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 a6dc5e17d78..5a68ead15c6 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 @@ -32152,6 +32152,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/isNullOrEmpty.kt"); } + @Test + @TestMetadata("kt45243.kt") + public void testKt45243() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/kt45243.kt"); + } + @Test @TestMetadata("require.kt") public void testRequire() throws Exception { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/contracts/ESDataFlowValue.kt b/compiler/frontend/src/org/jetbrains/kotlin/contracts/ESDataFlowValue.kt index ef85438c13b..6b8fd69d3cb 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/contracts/ESDataFlowValue.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/contracts/ESDataFlowValue.kt @@ -78,6 +78,6 @@ class ESReceiverWithDataFlowValue( */ class ESLambda(val lambda: KtLambdaExpression) : AbstractESValue(null) { override fun accept(visitor: ESExpressionVisitor): T { - throw IllegalStateException("Lambdas shouldn't be visited by ESExpressionVisitor") + return visitor.visitLambda(this) } -} \ No newline at end of file +} diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/ESExpressionVisitor.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/ESExpressionVisitor.kt index 9b54d54651d..3815d408c63 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/ESExpressionVisitor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/ESExpressionVisitor.kt @@ -30,4 +30,7 @@ interface ESExpressionVisitor { fun visitConstant(esConstant: ESConstant): T fun visitReceiver(esReceiver: ESReceiver): T -} \ No newline at end of file + + // ESLambda is invisible in this module + fun visitLambda(lambda: ESValue): T +} diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/InfoCollector.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/InfoCollector.kt index 428ff4fb859..aad613fd532 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/InfoCollector.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/InfoCollector.kt @@ -17,10 +17,7 @@ package org.jetbrains.kotlin.contracts.model.visitors import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.contracts.model.ConditionalEffect -import org.jetbrains.kotlin.contracts.model.ESEffect -import org.jetbrains.kotlin.contracts.model.ESExpressionVisitor -import org.jetbrains.kotlin.contracts.model.MutableContextInfo +import org.jetbrains.kotlin.contracts.model.* import org.jetbrains.kotlin.contracts.model.structure.* class InfoCollector(private val observedEffect: ESEffect, private val builtIns: KotlinBuiltIns) : ESExpressionVisitor { @@ -83,6 +80,8 @@ class InfoCollector(private val observedEffect: ESEffect, private val builtIns: override fun visitReceiver(esReceiver: ESReceiver): MutableContextInfo = MutableContextInfo.EMPTY + override fun visitLambda(lambda: ESValue): MutableContextInfo = MutableContextInfo.EMPTY + private fun inverted(block: () -> R): R { isInverted = isInverted.not() val result = block() diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/Reducer.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/Reducer.kt index 621dfa167b4..1eb6a0ed9a1 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/Reducer.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/Reducer.kt @@ -66,8 +66,8 @@ class Reducer(private val builtIns: KotlinBuiltIns) : ESExpressionVisitor assertNotNull(actual: T) { + contract { returns() implies (actual != null) } +} + +@ExperimentalContracts +fun test_1() { + assertNotNull { } +} + +@ExperimentalContracts +fun test_2() { + assertNotNull({ }) +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/kt45243.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/kt45243.kt new file mode 100644 index 00000000000..3059fd542a4 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/kt45243.kt @@ -0,0 +1,19 @@ +// ISSUE: KT-45243 + +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.contract + +@ExperimentalContracts +fun assertNotNull(actual: T) { + contract { returns() implies (actual != null) } +} + +@ExperimentalContracts +fun test_1() { + assertNotNull { } +} + +@ExperimentalContracts +fun test_2() { + assertNotNull({ }) +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/kt45243.txt b/compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/kt45243.txt new file mode 100644 index 00000000000..69e961eeba8 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/kt45243.txt @@ -0,0 +1,8 @@ +package + +@kotlin.contracts.ExperimentalContracts public fun assertNotNull(/*0*/ actual: T): kotlin.Unit + Returns(WILDCARD) -> actual != null + +@kotlin.contracts.ExperimentalContracts public fun test_1(): kotlin.Unit +@kotlin.contracts.ExperimentalContracts public fun test_2(): kotlin.Unit + 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 8fea46e8a27..6c2f4c9a2e7 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 @@ -32248,6 +32248,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/isNullOrEmpty.kt"); } + @Test + @TestMetadata("kt45243.kt") + public void testKt45243() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/kt45243.kt"); + } + @Test @TestMetadata("require.kt") public void testRequire() throws Exception { -- GitLab