From 6df97dd199e135aabe9e765612ba278b75561e97 Mon Sep 17 00:00:00 2001 From: Brian Norman Date: Tue, 7 Nov 2023 10:12:13 -0600 Subject: [PATCH] [FIR] Add test cases to prove resolution of backlog tickets ^KT-41728 Fixed ^KT-46586 Fixed ^KT-49696 Fixed ^KT-51160 Fixed ^KT-53308 Fixed --- ...CompilerTestFE10TestdataTestGenerated.java | 30 +++++++ ...sticCompilerFE10TestDataTestGenerated.java | 30 +++++++ ...eeOldFrontendDiagnosticsTestGenerated.java | 30 +++++++ ...siOldFrontendDiagnosticsTestGenerated.java | 30 +++++++ .../deadCode/smartCastAfterDeadCode.fir.kt | 10 +++ .../deadCode/smartCastAfterDeadCode.kt | 10 +++ .../reassignmentWithLambda.fir.kt | 21 +++++ .../reassignmentWithLambda.kt | 21 +++++ .../smartCasts/complexSealedContracts.fir.kt | 82 +++++++++++++++++++ .../smartCasts/complexSealedContracts.kt | 82 +++++++++++++++++++ .../capturedInlineModifiedBefore.fir.kt | 15 ++++ .../capturedInlineModifiedBefore.kt | 15 ++++ .../varnotnull/equalityAndIdentity.fir.kt | 39 +++++++++ .../varnotnull/equalityAndIdentity.kt | 39 +++++++++ .../test/runners/DiagnosticTestGenerated.java | 30 +++++++ 15 files changed, 484 insertions(+) create mode 100644 compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/smartCastAfterDeadCode.fir.kt create mode 100644 compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/smartCastAfterDeadCode.kt create mode 100644 compiler/testData/diagnostics/tests/controlFlowAnalysis/reassignmentWithLambda.fir.kt create mode 100644 compiler/testData/diagnostics/tests/controlFlowAnalysis/reassignmentWithLambda.kt create mode 100644 compiler/testData/diagnostics/tests/smartCasts/complexSealedContracts.fir.kt create mode 100644 compiler/testData/diagnostics/tests/smartCasts/complexSealedContracts.kt create mode 100644 compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInlineModifiedBefore.fir.kt create mode 100644 compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInlineModifiedBefore.kt create mode 100644 compiler/testData/diagnostics/tests/smartCasts/varnotnull/equalityAndIdentity.fir.kt create mode 100644 compiler/testData/diagnostics/tests/smartCasts/varnotnull/equalityAndIdentity.kt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java index 86d3dba04a9..4639378c162 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java @@ -7260,6 +7260,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/reassignmentInTryCatchWithJumps.kt"); } + @Test + @TestMetadata("reassignmentWithLambda.kt") + public void testReassignmentWithLambda() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/reassignmentWithLambda.kt"); + } + @Test @TestMetadata("referenceToPropertyInitializer.kt") public void testReferenceToPropertyInitializer() throws Exception { @@ -7544,6 +7550,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia public void testReturnInDeadLambda() throws Exception { runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/returnInDeadLambda.kt"); } + + @Test + @TestMetadata("smartCastAfterDeadCode.kt") + public void testSmartCastAfterDeadCode() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/smartCastAfterDeadCode.kt"); + } } @Nested @@ -31216,6 +31228,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/smartCasts/complexConditionsWithExcl.kt"); } + @Test + @TestMetadata("complexSealedContracts.kt") + public void testComplexSealedContracts() throws Exception { + runTest("compiler/testData/diagnostics/tests/smartCasts/complexSealedContracts.kt"); + } + @Test @TestMetadata("dataFlowInfoForArguments.kt") public void testDataFlowInfoForArguments() throws Exception { @@ -33217,6 +33235,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInClosureModifiedBefore.kt"); } + @Test + @TestMetadata("capturedInlineModifiedBefore.kt") + public void testCapturedInlineModifiedBefore() throws Exception { + runTest("compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInlineModifiedBefore.kt"); + } + @Test @TestMetadata("doWhileWithBreak.kt") public void testDoWhileWithBreak() throws Exception { @@ -33229,6 +33253,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/smartCasts/varnotnull/doWhileWithMiddleBreak.kt"); } + @Test + @TestMetadata("equalityAndIdentity.kt") + public void testEqualityAndIdentity() throws Exception { + runTest("compiler/testData/diagnostics/tests/smartCasts/varnotnull/equalityAndIdentity.kt"); + } + @Test @TestMetadata("forEach.kt") public void testForEach() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java index fba99fbef07..a06ebb1340c 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java @@ -7260,6 +7260,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/reassignmentInTryCatchWithJumps.kt"); } + @Test + @TestMetadata("reassignmentWithLambda.kt") + public void testReassignmentWithLambda() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/reassignmentWithLambda.kt"); + } + @Test @TestMetadata("referenceToPropertyInitializer.kt") public void testReferenceToPropertyInitializer() throws Exception { @@ -7544,6 +7550,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated public void testReturnInDeadLambda() throws Exception { runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/returnInDeadLambda.kt"); } + + @Test + @TestMetadata("smartCastAfterDeadCode.kt") + public void testSmartCastAfterDeadCode() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/smartCastAfterDeadCode.kt"); + } } @Nested @@ -31216,6 +31228,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/smartCasts/complexConditionsWithExcl.kt"); } + @Test + @TestMetadata("complexSealedContracts.kt") + public void testComplexSealedContracts() throws Exception { + runTest("compiler/testData/diagnostics/tests/smartCasts/complexSealedContracts.kt"); + } + @Test @TestMetadata("dataFlowInfoForArguments.kt") public void testDataFlowInfoForArguments() throws Exception { @@ -33217,6 +33235,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInClosureModifiedBefore.kt"); } + @Test + @TestMetadata("capturedInlineModifiedBefore.kt") + public void testCapturedInlineModifiedBefore() throws Exception { + runTest("compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInlineModifiedBefore.kt"); + } + @Test @TestMetadata("doWhileWithBreak.kt") public void testDoWhileWithBreak() throws Exception { @@ -33229,6 +33253,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/smartCasts/varnotnull/doWhileWithMiddleBreak.kt"); } + @Test + @TestMetadata("equalityAndIdentity.kt") + public void testEqualityAndIdentity() throws Exception { + runTest("compiler/testData/diagnostics/tests/smartCasts/varnotnull/equalityAndIdentity.kt"); + } + @Test @TestMetadata("forEach.kt") public void testForEach() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java index 751720c78d5..92cab02be81 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java @@ -7254,6 +7254,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/reassignmentInTryCatchWithJumps.kt"); } + @Test + @TestMetadata("reassignmentWithLambda.kt") + public void testReassignmentWithLambda() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/reassignmentWithLambda.kt"); + } + @Test @TestMetadata("referenceToPropertyInitializer.kt") public void testReferenceToPropertyInitializer() throws Exception { @@ -7538,6 +7544,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir public void testReturnInDeadLambda() throws Exception { runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/returnInDeadLambda.kt"); } + + @Test + @TestMetadata("smartCastAfterDeadCode.kt") + public void testSmartCastAfterDeadCode() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/smartCastAfterDeadCode.kt"); + } } @Nested @@ -31096,6 +31108,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/smartCasts/complexConditionsWithExcl.kt"); } + @Test + @TestMetadata("complexSealedContracts.kt") + public void testComplexSealedContracts() throws Exception { + runTest("compiler/testData/diagnostics/tests/smartCasts/complexSealedContracts.kt"); + } + @Test @TestMetadata("dataFlowInfoForArguments.kt") public void testDataFlowInfoForArguments() throws Exception { @@ -33097,6 +33115,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInClosureModifiedBefore.kt"); } + @Test + @TestMetadata("capturedInlineModifiedBefore.kt") + public void testCapturedInlineModifiedBefore() throws Exception { + runTest("compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInlineModifiedBefore.kt"); + } + @Test @TestMetadata("doWhileWithBreak.kt") public void testDoWhileWithBreak() throws Exception { @@ -33109,6 +33133,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/smartCasts/varnotnull/doWhileWithMiddleBreak.kt"); } + @Test + @TestMetadata("equalityAndIdentity.kt") + public void testEqualityAndIdentity() throws Exception { + runTest("compiler/testData/diagnostics/tests/smartCasts/varnotnull/equalityAndIdentity.kt"); + } + @Test @TestMetadata("forEach.kt") public void testForEach() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java index 54a31750421..54bca8c0c31 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java @@ -7260,6 +7260,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/reassignmentInTryCatchWithJumps.kt"); } + @Test + @TestMetadata("reassignmentWithLambda.kt") + public void testReassignmentWithLambda() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/reassignmentWithLambda.kt"); + } + @Test @TestMetadata("referenceToPropertyInitializer.kt") public void testReferenceToPropertyInitializer() throws Exception { @@ -7544,6 +7550,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia public void testReturnInDeadLambda() throws Exception { runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/returnInDeadLambda.kt"); } + + @Test + @TestMetadata("smartCastAfterDeadCode.kt") + public void testSmartCastAfterDeadCode() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/smartCastAfterDeadCode.kt"); + } } @Nested @@ -31216,6 +31228,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/smartCasts/complexConditionsWithExcl.kt"); } + @Test + @TestMetadata("complexSealedContracts.kt") + public void testComplexSealedContracts() throws Exception { + runTest("compiler/testData/diagnostics/tests/smartCasts/complexSealedContracts.kt"); + } + @Test @TestMetadata("dataFlowInfoForArguments.kt") public void testDataFlowInfoForArguments() throws Exception { @@ -33217,6 +33235,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInClosureModifiedBefore.kt"); } + @Test + @TestMetadata("capturedInlineModifiedBefore.kt") + public void testCapturedInlineModifiedBefore() throws Exception { + runTest("compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInlineModifiedBefore.kt"); + } + @Test @TestMetadata("doWhileWithBreak.kt") public void testDoWhileWithBreak() throws Exception { @@ -33229,6 +33253,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/smartCasts/varnotnull/doWhileWithMiddleBreak.kt"); } + @Test + @TestMetadata("equalityAndIdentity.kt") + public void testEqualityAndIdentity() throws Exception { + runTest("compiler/testData/diagnostics/tests/smartCasts/varnotnull/equalityAndIdentity.kt"); + } + @Test @TestMetadata("forEach.kt") public void testForEach() throws Exception { diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/smartCastAfterDeadCode.fir.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/smartCastAfterDeadCode.fir.kt new file mode 100644 index 00000000000..96fdf601aa3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/smartCastAfterDeadCode.fir.kt @@ -0,0 +1,10 @@ +// WITH_STDLIB +// ISSUE: KT-41728 + +fun foo(a: String?) { + if (a == null) { + return + "hi".length + } + a.length +} diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/smartCastAfterDeadCode.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/smartCastAfterDeadCode.kt new file mode 100644 index 00000000000..6393aadbca6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/smartCastAfterDeadCode.kt @@ -0,0 +1,10 @@ +// WITH_STDLIB +// ISSUE: KT-41728 + +fun foo(a: String?) { + if (a == null) { + return + "hi".length + } + a.length +} diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/reassignmentWithLambda.fir.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/reassignmentWithLambda.fir.kt new file mode 100644 index 00000000000..692855378be --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/reassignmentWithLambda.fir.kt @@ -0,0 +1,21 @@ +// WITH_STDLIB +// ISSUE: KT-49696 + +interface Listener { + fun added(item: Any) + fun removed(item: Any) +} + +val listeners = mutableListOf() + +fun smartCast(item: Any?) { + var current = item + if (current == null) { + current = Any() + listeners.forEach { it.added(current) } + } else { + listeners.forEach { it.removed(current) } + current = Any() + listeners.forEach { it.added(current) } + } +} diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/reassignmentWithLambda.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/reassignmentWithLambda.kt new file mode 100644 index 00000000000..1e736e0ccba --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/reassignmentWithLambda.kt @@ -0,0 +1,21 @@ +// WITH_STDLIB +// ISSUE: KT-49696 + +interface Listener { + fun added(item: Any) + fun removed(item: Any) +} + +val listeners = mutableListOf() + +fun smartCast(item: Any?) { + var current = item + if (current == null) { + current = Any() + listeners.forEach { it.added(current) } + } else { + listeners.forEach { it.removed(current) } + current = Any() + listeners.forEach { it.added(current) } + } +} diff --git a/compiler/testData/diagnostics/tests/smartCasts/complexSealedContracts.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/complexSealedContracts.fir.kt new file mode 100644 index 00000000000..fb555b367e2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/complexSealedContracts.fir.kt @@ -0,0 +1,82 @@ +// !OPT_IN: kotlin.contracts.ExperimentalContracts +// WITH_STDLIB +// ISSUE: KT-51160 + +import kotlin.contracts.* + +sealed interface AsyncStatus { + val value: T? + + data class Pending( + override val value: T? = null, + ) : AsyncStatus + + sealed interface Terminal : AsyncStatus + + data class Error( + val error: Throwable, + override val value: T? = null, + ) : Terminal + + data class Success( + override val value: T, + ) : Terminal +} + +fun AsyncStatus.isPending(): Boolean { + contract { + returns(true) implies (this@isPending is AsyncStatus.Pending) + returns(false) implies (this@isPending is AsyncStatus.Terminal) + } + return (this is AsyncStatus.Pending) +} + +fun AsyncStatus.isSuccess(): Boolean { + contract { returns(true) implies (this@isSuccess is AsyncStatus.Success) } + return (this is AsyncStatus.Success) +} + +fun AsyncStatus.Terminal.isSuccess(): Boolean { + contract { + returns(true) implies (this@isSuccess is AsyncStatus.Success) + returns(false) implies (this@isSuccess is AsyncStatus.Error) + } + return (this is AsyncStatus.Success) +} + +fun AsyncStatus.isError(): Boolean { + contract { returns(true) implies (this@isError is AsyncStatus.Error) } + return (this is AsyncStatus.Error) +} + +fun AsyncStatus.Terminal.isError(): Boolean { + contract { + returns(true) implies (this@isError is AsyncStatus.Error) + returns(false) implies (this@isError is AsyncStatus.Success) + } + return (this is AsyncStatus.Error) +} + +fun AsyncStatus.isTerminal(): Boolean { + contract { + returns(true) implies (this@isTerminal is AsyncStatus.Terminal) + returns(false) implies (this@isTerminal is AsyncStatus.Pending) + } + return (this is AsyncStatus.Terminal) +} + +fun main() { + val foo = AsyncStatus.Pending() + if (!foo.isPending()) { + if (foo.isSuccess()) { + nonNullPrint(foo.value) + } + if (foo.isError()) { + foo.error.printStackTrace() + } + } +} + +fun nonNullPrint(printMe: String) { + println(printMe) +} diff --git a/compiler/testData/diagnostics/tests/smartCasts/complexSealedContracts.kt b/compiler/testData/diagnostics/tests/smartCasts/complexSealedContracts.kt new file mode 100644 index 00000000000..06e330b9ea2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/complexSealedContracts.kt @@ -0,0 +1,82 @@ +// !OPT_IN: kotlin.contracts.ExperimentalContracts +// WITH_STDLIB +// ISSUE: KT-51160 + +import kotlin.contracts.* + +sealed interface AsyncStatus { + val value: T? + + data class Pending( + override val value: T? = null, + ) : AsyncStatus + + sealed interface Terminal : AsyncStatus + + data class Error( + val error: Throwable, + override val value: T? = null, + ) : Terminal + + data class Success( + override val value: T, + ) : Terminal +} + +fun AsyncStatus.isPending(): Boolean { + contract { + returns(true) implies (this@isPending is AsyncStatus.Pending) + returns(false) implies (this@isPending is AsyncStatus.Terminal) + } + return (this is AsyncStatus.Pending) +} + +fun AsyncStatus.isSuccess(): Boolean { + contract { returns(true) implies (this@isSuccess is AsyncStatus.Success) } + return (this is AsyncStatus.Success) +} + +fun AsyncStatus.Terminal.isSuccess(): Boolean { + contract { + returns(true) implies (this@isSuccess is AsyncStatus.Success) + returns(false) implies (this@isSuccess is AsyncStatus.Error) + } + return (this is AsyncStatus.Success) +} + +fun AsyncStatus.isError(): Boolean { + contract { returns(true) implies (this@isError is AsyncStatus.Error) } + return (this is AsyncStatus.Error) +} + +fun AsyncStatus.Terminal.isError(): Boolean { + contract { + returns(true) implies (this@isError is AsyncStatus.Error) + returns(false) implies (this@isError is AsyncStatus.Success) + } + return (this is AsyncStatus.Error) +} + +fun AsyncStatus.isTerminal(): Boolean { + contract { + returns(true) implies (this@isTerminal is AsyncStatus.Terminal) + returns(false) implies (this@isTerminal is AsyncStatus.Pending) + } + return (this is AsyncStatus.Terminal) +} + +fun main() { + val foo = AsyncStatus.Pending() + if (!foo.isPending()) { + if (foo.isSuccess()) { + nonNullPrint(foo.value) + } + if (foo.isError()) { + foo.error.printStackTrace() + } + } +} + +fun nonNullPrint(printMe: String) { + println(printMe) +} diff --git a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInlineModifiedBefore.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInlineModifiedBefore.fir.kt new file mode 100644 index 00000000000..305762bb4a4 --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInlineModifiedBefore.fir.kt @@ -0,0 +1,15 @@ +// WITH_STDLIB +// ISSUE: KT-46586 + +inline fun run(block: () -> Unit) = block() + +fun test() { + var label: String? = null + run { + label = "zzz" + } + if (label == null) { + label = "zzz" + } + label.isBlank() +} diff --git a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInlineModifiedBefore.kt b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInlineModifiedBefore.kt new file mode 100644 index 00000000000..bbf9d2fcdf3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInlineModifiedBefore.kt @@ -0,0 +1,15 @@ +// WITH_STDLIB +// ISSUE: KT-46586 + +inline fun run(block: () -> Unit) = block() + +fun test() { + var label: String? = null + run { + label = "zzz" + } + if (label == null) { + label = "zzz" + } + label.isBlank() +} diff --git a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/equalityAndIdentity.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/equalityAndIdentity.fir.kt new file mode 100644 index 00000000000..e166d1926e5 --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/equalityAndIdentity.fir.kt @@ -0,0 +1,39 @@ +// !OPT_IN: kotlin.contracts.ExperimentalContracts +// WITH_STDLIB +// ISSUE: KT-53308 + +import kotlin.contracts.* + +fun checkEquality(arg: E?) { contract { returns() implies (arg != null) } } +fun checkIdentity(arg: E?) { contract { returns() implies (arg !== null) } } +fun checkTrue(statement: Boolean) { contract { returns() implies statement } } +fun checkFalse(statement: Boolean) { contract { returns() implies !statement } } + +fun consume(arg: String) {} + +fun test(a: String?) { + a.let { + checkEquality(it) + consume(it) + } + a.let { + checkIdentity(it) + consume(it) + } + a.let { + checkTrue(it != null) + consume(it) + } + a.let { + checkTrue(it !== null) + consume(it) + } + a.let { + checkFalse(it == null) + consume(it) + } + a.let { + checkFalse(it === null) + consume(it) + } +} diff --git a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/equalityAndIdentity.kt b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/equalityAndIdentity.kt new file mode 100644 index 00000000000..65ecc89d3da --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/equalityAndIdentity.kt @@ -0,0 +1,39 @@ +// !OPT_IN: kotlin.contracts.ExperimentalContracts +// WITH_STDLIB +// ISSUE: KT-53308 + +import kotlin.contracts.* + +fun checkEquality(arg: E?) { contract { returns() implies (arg != null) } } +fun checkIdentity(arg: E?) { contract { returns() implies (arg !== null) } } +fun checkTrue(statement: Boolean) { contract { returns() implies statement } } +fun checkFalse(statement: Boolean) { contract { returns() implies !statement } } + +fun consume(arg: String) {} + +fun test(a: String?) { + a.let { + checkEquality(it) + consume(it) + } + a.let { + checkIdentity(it) + consume(it) + } + a.let { + checkTrue(it != null) + consume(it) + } + a.let { + checkTrue(it !== null) + consume(it) + } + a.let { + checkFalse(it == null) + consume(it) + } + a.let { + checkFalse(it === null) + consume(it) + } +} 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 796a196401a..2d9f05206e9 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 @@ -7260,6 +7260,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/reassignmentInTryCatchWithJumps.kt"); } + @Test + @TestMetadata("reassignmentWithLambda.kt") + public void testReassignmentWithLambda() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/reassignmentWithLambda.kt"); + } + @Test @TestMetadata("referenceToPropertyInitializer.kt") public void testReferenceToPropertyInitializer() throws Exception { @@ -7544,6 +7550,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { public void testReturnInDeadLambda() throws Exception { runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/returnInDeadLambda.kt"); } + + @Test + @TestMetadata("smartCastAfterDeadCode.kt") + public void testSmartCastAfterDeadCode() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/smartCastAfterDeadCode.kt"); + } } @Nested @@ -33204,6 +33216,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/smartCasts/complexConditionsWithExcl.kt"); } + @Test + @TestMetadata("complexSealedContracts.kt") + public void testComplexSealedContracts() throws Exception { + runTest("compiler/testData/diagnostics/tests/smartCasts/complexSealedContracts.kt"); + } + @Test @TestMetadata("dataFlowInfoForArguments.kt") public void testDataFlowInfoForArguments() throws Exception { @@ -35205,6 +35223,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInClosureModifiedBefore.kt"); } + @Test + @TestMetadata("capturedInlineModifiedBefore.kt") + public void testCapturedInlineModifiedBefore() throws Exception { + runTest("compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInlineModifiedBefore.kt"); + } + @Test @TestMetadata("doWhileWithBreak.kt") public void testDoWhileWithBreak() throws Exception { @@ -35217,6 +35241,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/smartCasts/varnotnull/doWhileWithMiddleBreak.kt"); } + @Test + @TestMetadata("equalityAndIdentity.kt") + public void testEqualityAndIdentity() throws Exception { + runTest("compiler/testData/diagnostics/tests/smartCasts/varnotnull/equalityAndIdentity.kt"); + } + @Test @TestMetadata("forEach.kt") public void testForEach() throws Exception {