From 565c61a702cfa2c2a52fa06cd7bed6823dacb417 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Mon, 28 Mar 2022 10:37:38 +0400 Subject: [PATCH] [FE 1.0] Fix false-negative INVALID_IF_AS_EXPRESSION_WARNING and NO_ELSE_IN_WHEN_WARNING ^KT-51711 Fixed --- ...CompilerTestFE10TestdataTestGenerated.java | 6 +++++ ...irOldFrontendDiagnosticsTestGenerated.java | 6 +++++ ...DiagnosticsWithLightTreeTestGenerated.java | 6 +++++ .../cfg/ControlFlowInformationProviderImpl.kt | 20 ++++++++++------- .../tests/controlStructures/kt51711.kt | 22 +++++++++++++++++++ .../tests/controlStructures/kt51711.txt | 5 +++++ .../test/runners/DiagnosticTestGenerated.java | 6 +++++ 7 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/controlStructures/kt51711.kt create mode 100644 compiler/testData/diagnostics/tests/controlStructures/kt51711.txt 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 55595365eed..e33d91f510d 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 @@ -6386,6 +6386,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/controlStructures/kt4310.kt"); } + @Test + @TestMetadata("kt51711.kt") + public void testKt51711() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlStructures/kt51711.kt"); + } + @Test @TestMetadata("kt657.kt") public void testKt657() 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 d0bb117fcfe..2bb468aa910 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 @@ -6386,6 +6386,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/controlStructures/kt4310.kt"); } + @Test + @TestMetadata("kt51711.kt") + public void testKt51711() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlStructures/kt51711.kt"); + } + @Test @TestMetadata("kt657.kt") public void testKt657() 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 77da4ef5824..4c41f2c7fca 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 @@ -6386,6 +6386,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/controlStructures/kt4310.kt"); } + @Test + @TestMetadata("kt51711.kt") + public void testKt51711() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlStructures/kt51711.kt"); + } + @Test @TestMetadata("kt657.kt") public void testKt657() throws Exception { diff --git a/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt b/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt index 1429c4ff3c1..035cbc67f13 100644 --- a/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt +++ b/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt @@ -955,20 +955,23 @@ class ControlFlowInformationProviderImpl private constructor( for (element in instruction.owner.getValueElements(value)) { if (element !is KtIfExpression) continue - if (element.isUsedAsExpression(trace.bindingContext)) { - val thenExpression = element.then - val elseExpression = element.`else` + val thenExpression = element.then + val elseExpression = element.`else` + val isEhxaustive = thenExpression != null && elseExpression != null - if (thenExpression == null || elseExpression == null) { + if (element.isUsedAsExpression(trace.bindingContext)) { + if (!isEhxaustive) { trace.report(INVALID_IF_AS_EXPRESSION.on(element.ifKeyword)) } else { checkImplicitCastOnConditionalExpression(element) } } else if (!languageVersionSettings.supportsFeature(LanguageFeature.ProhibitNonExhaustiveIfInRhsOfElvis)) { - val parent = element.deparenthesizedParent - if (parent is KtBinaryExpression) { - if (parent.operationToken === KtTokens.ELVIS) { - trace.report(INVALID_IF_AS_EXPRESSION_WARNING.on(element.getIfKeyword())) + if (!isEhxaustive) { + val parent = element.deparenthesizedParent + if (parent is KtBinaryExpression) { + if (parent.operationToken === KtTokens.ELVIS) { + trace.report(INVALID_IF_AS_EXPRESSION_WARNING.on(element.getIfKeyword())) + } } } } @@ -1067,6 +1070,7 @@ class ControlFlowInformationProviderImpl private constructor( if ( !usedAsExpression && missingCases.isNotEmpty() && + elseEntry == null && !languageVersionSettings.supportsFeature(LanguageFeature.ProhibitNonExhaustiveIfInRhsOfElvis) ) { val parent = element.deparenthesizedParent diff --git a/compiler/testData/diagnostics/tests/controlStructures/kt51711.kt b/compiler/testData/diagnostics/tests/controlStructures/kt51711.kt new file mode 100644 index 00000000000..5c031d7d0a0 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlStructures/kt51711.kt @@ -0,0 +1,22 @@ +// FIR_IDENTICAL +// LANGUAGE: -ProhibitNonExhaustiveIfInRhsOfElvis +// ISSUE: KT-51711 +// WITH_STDLIB + +private fun fake(a: String?) {} + +fun test_1(x: String?, y: String?) { + while (true) { + x ?: if (y == null) break else fake(y) + } +} + + +fun test_2(x: String?, y: String?) { + while (true) { + x ?: when { + true -> break + else -> y?.filter { it.isLowerCase() } + } + } +} diff --git a/compiler/testData/diagnostics/tests/controlStructures/kt51711.txt b/compiler/testData/diagnostics/tests/controlStructures/kt51711.txt new file mode 100644 index 00000000000..49f468e5c50 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlStructures/kt51711.txt @@ -0,0 +1,5 @@ +package + +private fun fake(/*0*/ a: kotlin.String?): kotlin.Unit +public fun test_1(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.String?): kotlin.Unit +public fun test_2(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.String?): 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 2954cf663b6..1a247e0aa1c 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 @@ -6392,6 +6392,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/controlStructures/kt4310.kt"); } + @Test + @TestMetadata("kt51711.kt") + public void testKt51711() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlStructures/kt51711.kt"); + } + @Test @TestMetadata("kt657.kt") public void testKt657() throws Exception {