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 2788b3e472f..a84498b6402 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 @@ -32089,6 +32089,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/when/whenAndLambdaWithExpectedType.kt"); } + @Test + @TestMetadata("whenOnNothing.kt") + public void testWhenOnNothing() throws Exception { + runTest("compiler/testData/diagnostics/tests/when/whenOnNothing.kt"); + } + @Test @TestMetadata("WhenTypeDisjunctions.kt") public void testWhenTypeDisjunctions() 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 d2f1c32df88..9354c4d7d27 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 @@ -32089,6 +32089,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/when/whenAndLambdaWithExpectedType.kt"); } + @Test + @TestMetadata("whenOnNothing.kt") + public void testWhenOnNothing() throws Exception { + runTest("compiler/testData/diagnostics/tests/when/whenOnNothing.kt"); + } + @Test @TestMetadata("WhenTypeDisjunctions.kt") public void testWhenTypeDisjunctions() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt index 2595b1c3307..7c15bf19f23 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt @@ -10,7 +10,9 @@ import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.diagnostics.WhenMissingCase import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.FirEnumEntry +import org.jetbrains.kotlin.fir.declarations.FirRegularClass +import org.jetbrains.kotlin.fir.declarations.getSealedClassInheritors import org.jetbrains.kotlin.fir.declarations.utils.collectEnumEntries import org.jetbrains.kotlin.fir.declarations.utils.modality import org.jetbrains.kotlin.fir.expressions.* @@ -33,7 +35,8 @@ class FirWhenExhaustivenessTransformer(private val bodyResolveComponents: BodyRe private val exhaustivenessCheckers = listOf( WhenOnBooleanExhaustivenessChecker, WhenOnEnumExhaustivenessChecker, - WhenOnSealedClassExhaustivenessChecker + WhenOnSealedClassExhaustivenessChecker, + WhenOnNothingExhaustivenessChecker ) @OptIn(ExperimentalStdlibApi::class) @@ -389,3 +392,18 @@ private object WhenOnSealedClassExhaustivenessChecker : WhenExhaustivenessChecke } } } + +private object WhenOnNothingExhaustivenessChecker : WhenExhaustivenessChecker() { + override fun isApplicable(subjectType: ConeKotlinType, session: FirSession): Boolean { + return subjectType.isNullableNothing || subjectType.isNothing + } + + override fun computeMissingCases( + whenExpression: FirWhenExpression, + subjectType: ConeKotlinType, + session: FirSession, + destination: MutableCollection + ) { + // Nothing has no branches. The null case for `Nothing?` is handled by WhenOnNullableExhaustivenessChecker + } +} diff --git a/compiler/testData/diagnostics/tests/when/whenOnNothing.fir.kt b/compiler/testData/diagnostics/tests/when/whenOnNothing.fir.kt new file mode 100644 index 00000000000..1eefde92022 --- /dev/null +++ b/compiler/testData/diagnostics/tests/when/whenOnNothing.fir.kt @@ -0,0 +1,11 @@ +// !DIAGNOSTICS: -UNREACHABLE_CODE + +// exhaustive +fun test1(n: Nothing) = when (n) { } +fun test2(n: Nothing?) = when (n) { + null -> {} +} + +// not exhaustive +fun test3(n: Nothing?) = when (n) { +} diff --git a/compiler/testData/diagnostics/tests/when/whenOnNothing.kt b/compiler/testData/diagnostics/tests/when/whenOnNothing.kt new file mode 100644 index 00000000000..8743cfbe238 --- /dev/null +++ b/compiler/testData/diagnostics/tests/when/whenOnNothing.kt @@ -0,0 +1,11 @@ +// !DIAGNOSTICS: -UNREACHABLE_CODE + +// exhaustive +fun test1(n: Nothing) = when (n) { } +fun test2(n: Nothing?) = when (n) { + null -> {} +} + +// not exhaustive +fun test3(n: Nothing?) = when (n) { +} diff --git a/compiler/testData/diagnostics/tests/when/whenOnNothing.txt b/compiler/testData/diagnostics/tests/when/whenOnNothing.txt new file mode 100644 index 00000000000..8fa146ec65a --- /dev/null +++ b/compiler/testData/diagnostics/tests/when/whenOnNothing.txt @@ -0,0 +1,3 @@ +package + +public fun foo(/*0*/ n: kotlin.Nothing, /*1*/ nn: kotlin.Nothing?): 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 e726ac8d227..cde4d2a6ce6 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 @@ -32185,6 +32185,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/when/whenAndLambdaWithExpectedType.kt"); } + @Test + @TestMetadata("whenOnNothing.kt") + public void testWhenOnNothing() throws Exception { + runTest("compiler/testData/diagnostics/tests/when/whenOnNothing.kt"); + } + @Test @TestMetadata("WhenTypeDisjunctions.kt") public void testWhenTypeDisjunctions() throws Exception { diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index eb28f1861fd..e40e8bf3bbc 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -32089,6 +32089,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/when/whenAndLambdaWithExpectedType.kt"); } + @Test + @TestMetadata("whenOnNothing.kt") + public void testWhenOnNothing() throws Exception { + runTest("compiler/testData/diagnostics/tests/when/whenOnNothing.kt"); + } + @Test @TestMetadata("WhenTypeDisjunctions.kt") public void testWhenTypeDisjunctions() throws Exception {