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 0f011eedb45..5246755f9c8 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 @@ -31681,6 +31681,18 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/when/NonExhaustiveWarningNull.kt"); } + @Test + @TestMetadata("nonExhaustiveWhenStatement_1_6.kt") + public void testNonExhaustiveWhenStatement_1_6() throws Exception { + runTest("compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_6.kt"); + } + + @Test + @TestMetadata("nonExhaustiveWhenStatement_1_7.kt") + public void testNonExhaustiveWhenStatement_1_7() throws Exception { + runTest("compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_7.kt"); + } + @Test @TestMetadata("NonExhaustiveWithNullabilityCheck.kt") public void testNonExhaustiveWithNullabilityCheck() 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 57abab6d025..199bb8b83d6 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 @@ -31681,6 +31681,18 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/when/NonExhaustiveWarningNull.kt"); } + @Test + @TestMetadata("nonExhaustiveWhenStatement_1_6.kt") + public void testNonExhaustiveWhenStatement_1_6() throws Exception { + runTest("compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_6.kt"); + } + + @Test + @TestMetadata("nonExhaustiveWhenStatement_1_7.kt") + public void testNonExhaustiveWhenStatement_1_7() throws Exception { + runTest("compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_7.kt"); + } + @Test @TestMetadata("NonExhaustiveWithNullabilityCheck.kt") public void testNonExhaustiveWithNullabilityCheck() 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 ae70fd37de5..e093aa59958 100644 --- a/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt +++ b/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt @@ -62,6 +62,7 @@ import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils.* import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils import org.jetbrains.kotlin.types.isFlexible +import org.jetbrains.kotlin.types.typeUtil.isBooleanOrNullableBoolean import org.jetbrains.kotlin.util.OperatorNameConventions class ControlFlowInformationProviderImpl private constructor( @@ -1024,19 +1025,19 @@ class ControlFlowInformationProviderImpl private constructor( } continue } - if (!usedAsExpression) { - val enumClassDescriptor = WhenChecker.getClassDescriptorOfTypeIfEnum(subjectType) - if (enumClassDescriptor != null) { - val enumMissingCases = WhenChecker.getEnumMissingCases(element, context, enumClassDescriptor) - if (enumMissingCases.isNotEmpty()) { - trace.report(NON_EXHAUSTIVE_WHEN.on(element, enumMissingCases)) - } + if (!usedAsExpression && missingCases.isNotEmpty()) { + val kind = when { + WhenChecker.getClassDescriptorOfTypeIfSealed(subjectType) != null -> AlgebraicTypeKind.Sealed + WhenChecker.getClassDescriptorOfTypeIfEnum(subjectType) != null -> AlgebraicTypeKind.Enum + subjectType?.isBooleanOrNullableBoolean() == true -> AlgebraicTypeKind.Boolean + else -> null } - val sealedClassDescriptor = WhenChecker.getClassDescriptorOfTypeIfSealed(subjectType) - if (sealedClassDescriptor != null) { - val sealedMissingCases = WhenChecker.getSealedMissingCases(element, context, sealedClassDescriptor) - if (sealedMissingCases.isNotEmpty()) { - trace.report(NON_EXHAUSTIVE_WHEN_ON_SEALED_CLASS.on(element, sealedMissingCases)) + + if (kind != null) { + if (languageVersionSettings.supportsFeature(LanguageFeature.ProhibitNonExhaustiveWhenOnAlgebraicTypes)) { + trace.report(NO_ELSE_IN_WHEN.on(element, missingCases)) + } else { + trace.report(NON_EXHAUSTIVE_WHEN_STATEMENT.on(element, kind.displayName, missingCases)) } } } @@ -1045,6 +1046,12 @@ class ControlFlowInformationProviderImpl private constructor( } } + private enum class AlgebraicTypeKind(val displayName: String) { + Sealed("sealed class/interface"), + Enum("enum"), + Boolean("Boolean") + } + private fun checkConstructorConsistency() { when (subroutine) { is KtClassOrObject -> ConstructorConsistencyChecker.check(subroutine, trace, pseudocode, pseudocodeVariablesData) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 193b6ee2523..8a2dfbb9824 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -1080,6 +1080,7 @@ public interface Errors { DiagnosticFactory0 REDUNDANT_ELSE_IN_WHEN = DiagnosticFactory0.create(WARNING, ELSE_ENTRY); DiagnosticFactory1> NO_ELSE_IN_WHEN = DiagnosticFactory1.create(ERROR, WHEN_EXPRESSION); DiagnosticFactory1> NON_EXHAUSTIVE_WHEN = DiagnosticFactory1.create(WARNING, WHEN_EXPRESSION); + DiagnosticFactory2> NON_EXHAUSTIVE_WHEN_STATEMENT = DiagnosticFactory2.create(WARNING, WHEN_EXPRESSION); DiagnosticFactory1> NON_EXHAUSTIVE_WHEN_ON_SEALED_CLASS = DiagnosticFactory1.create(INFO, WHEN_EXPRESSION); DiagnosticFactory1 EXPECT_TYPE_IN_WHEN_WITHOUT_ELSE = DiagnosticFactory1.create(ERROR, WHEN_EXPRESSION); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index a194d8ad349..fd3ef54139e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -631,6 +631,7 @@ public class DefaultErrorMessages { MAP.put(NO_ELSE_IN_WHEN, "''when'' expression must be exhaustive, add necessary {0}", RENDER_WHEN_MISSING_CASES); MAP.put(NON_EXHAUSTIVE_WHEN, "''when'' expression on enum is recommended to be exhaustive, add {0}", RENDER_WHEN_MISSING_CASES); + MAP.put(NON_EXHAUSTIVE_WHEN_STATEMENT, "Non exhaustive ''when'' statements on {0} will be prohibited in 1.7, add {1}", STRING, RENDER_WHEN_MISSING_CASES); MAP.put(NON_EXHAUSTIVE_WHEN_ON_SEALED_CLASS, "''when'' expression on sealed classes is recommended to be exhaustive, add {0}", RENDER_WHEN_MISSING_CASES); MAP.put(EXPECT_TYPE_IN_WHEN_WITHOUT_ELSE, "'when' with expect {0} as subject can not be exhaustive without else branch", STRING); diff --git a/compiler/testData/diagnostics/tests/j+k/kt2619.kt b/compiler/testData/diagnostics/tests/j+k/kt2619.kt index 92feeff2333..62359d42ae7 100644 --- a/compiler/testData/diagnostics/tests/j+k/kt2619.kt +++ b/compiler/testData/diagnostics/tests/j+k/kt2619.kt @@ -1,7 +1,7 @@ //FILE: foo.kt fun main() { val c: Type - when (c) { + when (c) { } } diff --git a/compiler/testData/diagnostics/tests/reassignment/when.fir.kt b/compiler/testData/diagnostics/tests/reassignment/when.fir.kt new file mode 100644 index 00000000000..65a9d862ece --- /dev/null +++ b/compiler/testData/diagnostics/tests/reassignment/when.fir.kt @@ -0,0 +1,10 @@ +// !DIAGNOSTICS: -UNUSED_VALUE + +fun foo(f: Boolean): Int { + val i: Int + when (f) { + true -> i = 1 + } + i = 3 + return i +} diff --git a/compiler/testData/diagnostics/tests/reassignment/when.kt b/compiler/testData/diagnostics/tests/reassignment/when.kt index 2ced4c7f021..26ef1b78001 100644 --- a/compiler/testData/diagnostics/tests/reassignment/when.kt +++ b/compiler/testData/diagnostics/tests/reassignment/when.kt @@ -1,11 +1,10 @@ -// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_VALUE fun foo(f: Boolean): Int { val i: Int - when (f) { + when (f) { true -> i = 1 } i = 3 return i -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/smartCasts/propertyAsCondition.kt b/compiler/testData/diagnostics/tests/smartCasts/propertyAsCondition.kt index 9a0d88c99b4..0597379cea1 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/propertyAsCondition.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/propertyAsCondition.kt @@ -7,7 +7,7 @@ fun foo(my: My) { if (my.x != null) { // my.x should be smart-cast if (my.x) doIt() - when (my.x) { + when (my.x) { true -> doIt() } when { @@ -20,11 +20,11 @@ fun bar(x: Boolean?) { if (x != null) { // x should be smart-cast if (x) doIt() - when (x) { + when (x) { true -> doIt() } when { x -> doIt() } } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/when/ExhaustiveValOverConditionalInit.kt b/compiler/testData/diagnostics/tests/when/ExhaustiveValOverConditionalInit.kt index 2d9cb6ed869..7203d4d45c4 100644 --- a/compiler/testData/diagnostics/tests/when/ExhaustiveValOverConditionalInit.kt +++ b/compiler/testData/diagnostics/tests/when/ExhaustiveValOverConditionalInit.kt @@ -27,7 +27,7 @@ fun bar(a: Boolean, b: Boolean): Int { if (a) { x = 1 } - when (b) { + when (b) { false -> x = 3 } return x diff --git a/compiler/testData/diagnostics/tests/when/ExhaustiveVarOverConditionalInit.kt b/compiler/testData/diagnostics/tests/when/ExhaustiveVarOverConditionalInit.kt index 4ad5438cfa0..88bb89dba7a 100644 --- a/compiler/testData/diagnostics/tests/when/ExhaustiveVarOverConditionalInit.kt +++ b/compiler/testData/diagnostics/tests/when/ExhaustiveVarOverConditionalInit.kt @@ -26,7 +26,7 @@ fun bar(a: Boolean, b: Boolean): Int { if (a) { x = 1 } - when (b) { + when (b) { false -> x = 3 } return x diff --git a/compiler/testData/diagnostics/tests/when/NonExhaustiveWarning.kt b/compiler/testData/diagnostics/tests/when/NonExhaustiveWarning.kt index 5e6ef130882..3dfba4f220c 100644 --- a/compiler/testData/diagnostics/tests/when/NonExhaustiveWarning.kt +++ b/compiler/testData/diagnostics/tests/when/NonExhaustiveWarning.kt @@ -15,7 +15,7 @@ enum class X { A, B, C, D } fun foo(arg: X): String { var res = "XXX" - when (arg) { + when (arg) { X.A -> res = "A" X.B -> res = "B" } diff --git a/compiler/testData/diagnostics/tests/when/NonExhaustiveWarningForSealedClass.kt b/compiler/testData/diagnostics/tests/when/NonExhaustiveWarningForSealedClass.kt index 845ba67b987..dad73acc4d0 100644 --- a/compiler/testData/diagnostics/tests/when/NonExhaustiveWarningForSealedClass.kt +++ b/compiler/testData/diagnostics/tests/when/NonExhaustiveWarningForSealedClass.kt @@ -22,7 +22,7 @@ object Last : S() fun use(s: String) = s fun foo(s: S) { - when (s) { + when (s) { First -> {} is Derived -> use(s.s) } diff --git a/compiler/testData/diagnostics/tests/when/NonExhaustiveWarningNull.fir.kt b/compiler/testData/diagnostics/tests/when/NonExhaustiveWarningNull.fir.kt new file mode 100644 index 00000000000..2d3da1ec811 --- /dev/null +++ b/compiler/testData/diagnostics/tests/when/NonExhaustiveWarningNull.fir.kt @@ -0,0 +1,27 @@ +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-152 + * PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1 + * expressions, when-expression, exhaustive-when-expressions -> paragraph 1 -> sentence 1 + * expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 9 + * expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 10 + * expressions, when-expression -> paragraph 9 -> sentence 2 + * control--and-data-flow-analysis, performing-analysis-on-the-control-flow-graph, variable-initialization-analysis -> paragraph 2 -> sentence 1 + * control--and-data-flow-analysis, performing-analysis-on-the-control-flow-graph, variable-initialization-analysis -> paragraph 2 -> sentence 3 + */ + +// Base for KT-6227 +enum class X { A, B, C, D } + +fun foo(arg: X?): String { + var res = "XXX" + // Should we report something here? Probably not, null is not an enum entry + when (arg) { + X.A -> res = "A" + X.B -> res = "B" + X.C -> res = "C" + X.D -> res = "D" + } + return res +} diff --git a/compiler/testData/diagnostics/tests/when/NonExhaustiveWarningNull.kt b/compiler/testData/diagnostics/tests/when/NonExhaustiveWarningNull.kt index 92e628921ac..b62ffae37ce 100644 --- a/compiler/testData/diagnostics/tests/when/NonExhaustiveWarningNull.kt +++ b/compiler/testData/diagnostics/tests/when/NonExhaustiveWarningNull.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL /* * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) * @@ -17,12 +16,11 @@ enum class X { A, B, C, D } fun foo(arg: X?): String { var res = "XXX" - // Should we report something here? Probably not, null is not an enum entry - when (arg) { + when (arg) { X.A -> res = "A" X.B -> res = "B" X.C -> res = "C" X.D -> res = "D" } return res -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_6.fir.kt b/compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_6.fir.kt new file mode 100644 index 00000000000..d93e09154b8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_6.fir.kt @@ -0,0 +1,154 @@ +// !LANGUAGE: -ProhibitNonExhaustiveWhenOnLogicalTypes + +enum class SomeEnum { + A, B +} + +sealed class Base { + class A : Base() + class B : Base() +} + +sealed interface IBase { + interface A : IBase + interface B : IBase +} + +// ------------------ not null ------------------ + +fun test_1(x: SomeEnum) { + when (x) { + SomeEnum.A -> "" + } +} + +fun test_2(x: Base) { + when (x) { + is Base.A -> "" + } +} + +fun test_3(x: IBase) { + when (x) { + is IBase.A -> "" + } +} + +fun test_4(x: Boolean) { + when (x) { + true -> "" + } +} + +// ------------------ nullable ------------------ + +fun test_5(x: SomeEnum?) { + when (x) { + SomeEnum.A -> "" + SomeEnum.B -> "" + } + + when (x) { + SomeEnum.A -> "" + null -> "" + } +} + +fun test_6(x: Base?) { + when (x) { + is Base.A -> "" + is Base.B -> "" + } + + when (x) { + is Base.A -> "" + null -> "" + } +} + +fun test_7(x: IBase?) { + when (x) { + is IBase.A -> "" + is IBase.B -> "" + } + when (x) { + is IBase.A -> "" + null -> "" + } +} + +fun test_8(x: Boolean?) { + when (x) { + true -> "" + false -> "" + } + + when (x) { + true -> "" + null -> "" + } +} + +// ------------------ with else ------------------ + +fun test_9(x: SomeEnum?) { + when (x) { + SomeEnum.A -> "" + else -> "" + } +} + +fun test_10(x: Base?) { + when (x) { + is Base.A -> "" + else -> "" + } +} + +fun test_11(x: IBase?) { + when (x) { + is IBase.A -> "" + else -> "" + } +} + +fun test_12(x: Boolean?) { + when (x) { + true -> "" + else -> "" + } +} + +// ------------------ exhaustive ------------------ + +fun test_13(x: SomeEnum?) { + when (x) { + SomeEnum.A -> "" + SomeEnum.B -> "" + null -> "" + } +} + +fun test_14(x: Base?) { + when (x) { + is Base.A -> "" + is Base.B -> "" + null -> "" + } +} + +fun test_15(x: IBase?) { + when (x) { + is IBase.A -> "" + is IBase.B -> "" + null -> "" + } +} + +fun test_16(x: Boolean?) { + when (x) { + true -> "" + false -> "" + null -> "" + } +} diff --git a/compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_6.kt b/compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_6.kt new file mode 100644 index 00000000000..c6b9ecec650 --- /dev/null +++ b/compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_6.kt @@ -0,0 +1,154 @@ +// !LANGUAGE: -ProhibitNonExhaustiveWhenOnAlgebraicTypes + +enum class SomeEnum { + A, B +} + +sealed class Base { + class A : Base() + class B : Base() +} + +sealed interface IBase { + interface A : IBase + interface B : IBase +} + +// ------------------ not null ------------------ + +fun test_1(x: SomeEnum) { + when (x) { + SomeEnum.A -> "" + } +} + +fun test_2(x: Base) { + when (x) { + is Base.A -> "" + } +} + +fun test_3(x: IBase) { + when (x) { + is IBase.A -> "" + } +} + +fun test_4(x: Boolean) { + when (x) { + true -> "" + } +} + +// ------------------ nullable ------------------ + +fun test_5(x: SomeEnum?) { + when (x) { + SomeEnum.A -> "" + SomeEnum.B -> "" + } + + when (x) { + SomeEnum.A -> "" + null -> "" + } +} + +fun test_6(x: Base?) { + when (x) { + is Base.A -> "" + is Base.B -> "" + } + + when (x) { + is Base.A -> "" + null -> "" + } +} + +fun test_7(x: IBase?) { + when (x) { + is IBase.A -> "" + is IBase.B -> "" + } + when (x) { + is IBase.A -> "" + null -> "" + } +} + +fun test_8(x: Boolean?) { + when (x) { + true -> "" + false -> "" + } + + when (x) { + true -> "" + null -> "" + } +} + +// ------------------ with else ------------------ + +fun test_9(x: SomeEnum?) { + when (x) { + SomeEnum.A -> "" + else -> "" + } +} + +fun test_10(x: Base?) { + when (x) { + is Base.A -> "" + else -> "" + } +} + +fun test_11(x: IBase?) { + when (x) { + is IBase.A -> "" + else -> "" + } +} + +fun test_12(x: Boolean?) { + when (x) { + true -> "" + else -> "" + } +} + +// ------------------ exhaustive ------------------ + +fun test_13(x: SomeEnum?) { + when (x) { + SomeEnum.A -> "" + SomeEnum.B -> "" + null -> "" + } +} + +fun test_14(x: Base?) { + when (x) { + is Base.A -> "" + is Base.B -> "" + null -> "" + } +} + +fun test_15(x: IBase?) { + when (x) { + is IBase.A -> "" + is IBase.B -> "" + null -> "" + } +} + +fun test_16(x: Boolean?) { + when (x) { + true -> "" + false -> "" + null -> "" + } +} diff --git a/compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_6.txt b/compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_6.txt new file mode 100644 index 00000000000..4357927d632 --- /dev/null +++ b/compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_6.txt @@ -0,0 +1,78 @@ +package + +public fun test_1(/*0*/ x: SomeEnum): kotlin.Unit +public fun test_10(/*0*/ x: Base?): kotlin.Unit +public fun test_11(/*0*/ x: IBase?): kotlin.Unit +public fun test_12(/*0*/ x: kotlin.Boolean?): kotlin.Unit +public fun test_13(/*0*/ x: SomeEnum?): kotlin.Unit +public fun test_14(/*0*/ x: Base?): kotlin.Unit +public fun test_15(/*0*/ x: IBase?): kotlin.Unit +public fun test_16(/*0*/ x: kotlin.Boolean?): kotlin.Unit +public fun test_2(/*0*/ x: Base): kotlin.Unit +public fun test_3(/*0*/ x: IBase): kotlin.Unit +public fun test_4(/*0*/ x: kotlin.Boolean): kotlin.Unit +public fun test_5(/*0*/ x: SomeEnum?): kotlin.Unit +public fun test_6(/*0*/ x: Base?): kotlin.Unit +public fun test_7(/*0*/ x: IBase?): kotlin.Unit +public fun test_8(/*0*/ x: kotlin.Boolean?): kotlin.Unit +public fun test_9(/*0*/ x: SomeEnum?): kotlin.Unit + +public sealed class Base { + protected constructor Base() + 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 class A : Base { + public 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 class B : Base { + public constructor B() + 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 sealed interface IBase { + 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 interface A : IBase { + 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 interface B : IBase { + 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 enum class SomeEnum : kotlin.Enum { + enum entry A + + enum entry B + + private constructor SomeEnum() + public final override /*1*/ /*fake_override*/ val name: kotlin.String + public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SomeEnum): kotlin.Int + public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit + public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class! + public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): SomeEnum + public final /*synthesized*/ fun values(): kotlin.Array +} diff --git a/compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_7.fir.kt b/compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_7.fir.kt new file mode 100644 index 00000000000..42d35b9098e --- /dev/null +++ b/compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_7.fir.kt @@ -0,0 +1,154 @@ +// !LANGUAGE: +ProhibitNonExhaustiveWhenOnLogicalTypes + +enum class SomeEnum { + A, B +} + +sealed class Base { + class A : Base() + class B : Base() +} + +sealed interface IBase { + interface A : IBase + interface B : IBase +} + +// ------------------ not null ------------------ + +fun test_1(x: SomeEnum) { + when (x) { + SomeEnum.A -> "" + } +} + +fun test_2(x: Base) { + when (x) { + is Base.A -> "" + } +} + +fun test_3(x: IBase) { + when (x) { + is IBase.A -> "" + } +} + +fun test_4(x: Boolean) { + when (x) { + true -> "" + } +} + +// ------------------ nullable ------------------ + +fun test_5(x: SomeEnum?) { + when (x) { + SomeEnum.A -> "" + SomeEnum.B -> "" + } + + when (x) { + SomeEnum.A -> "" + null -> "" + } +} + +fun test_6(x: Base?) { + when (x) { + is Base.A -> "" + is Base.B -> "" + } + + when (x) { + is Base.A -> "" + null -> "" + } +} + +fun test_7(x: IBase?) { + when (x) { + is IBase.A -> "" + is IBase.B -> "" + } + when (x) { + is IBase.A -> "" + null -> "" + } +} + +fun test_8(x: Boolean?) { + when (x) { + true -> "" + false -> "" + } + + when (x) { + true -> "" + null -> "" + } +} + +// ------------------ with else ------------------ + +fun test_9(x: SomeEnum?) { + when (x) { + SomeEnum.A -> "" + else -> "" + } +} + +fun test_10(x: Base?) { + when (x) { + is Base.A -> "" + else -> "" + } +} + +fun test_11(x: IBase?) { + when (x) { + is IBase.A -> "" + else -> "" + } +} + +fun test_12(x: Boolean?) { + when (x) { + true -> "" + else -> "" + } +} + +// ------------------ exhaustive ------------------ + +fun test_13(x: SomeEnum?) { + when (x) { + SomeEnum.A -> "" + SomeEnum.B -> "" + null -> "" + } +} + +fun test_14(x: Base?) { + when (x) { + is Base.A -> "" + is Base.B -> "" + null -> "" + } +} + +fun test_15(x: IBase?) { + when (x) { + is IBase.A -> "" + is IBase.B -> "" + null -> "" + } +} + +fun test_16(x: Boolean?) { + when (x) { + true -> "" + false -> "" + null -> "" + } +} diff --git a/compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_7.kt b/compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_7.kt new file mode 100644 index 00000000000..dc62a7ea2e9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_7.kt @@ -0,0 +1,154 @@ +// !LANGUAGE: +ProhibitNonExhaustiveWhenOnAlgebraicTypes + +enum class SomeEnum { + A, B +} + +sealed class Base { + class A : Base() + class B : Base() +} + +sealed interface IBase { + interface A : IBase + interface B : IBase +} + +// ------------------ not null ------------------ + +fun test_1(x: SomeEnum) { + when (x) { + SomeEnum.A -> "" + } +} + +fun test_2(x: Base) { + when (x) { + is Base.A -> "" + } +} + +fun test_3(x: IBase) { + when (x) { + is IBase.A -> "" + } +} + +fun test_4(x: Boolean) { + when (x) { + true -> "" + } +} + +// ------------------ nullable ------------------ + +fun test_5(x: SomeEnum?) { + when (x) { + SomeEnum.A -> "" + SomeEnum.B -> "" + } + + when (x) { + SomeEnum.A -> "" + null -> "" + } +} + +fun test_6(x: Base?) { + when (x) { + is Base.A -> "" + is Base.B -> "" + } + + when (x) { + is Base.A -> "" + null -> "" + } +} + +fun test_7(x: IBase?) { + when (x) { + is IBase.A -> "" + is IBase.B -> "" + } + when (x) { + is IBase.A -> "" + null -> "" + } +} + +fun test_8(x: Boolean?) { + when (x) { + true -> "" + false -> "" + } + + when (x) { + true -> "" + null -> "" + } +} + +// ------------------ with else ------------------ + +fun test_9(x: SomeEnum?) { + when (x) { + SomeEnum.A -> "" + else -> "" + } +} + +fun test_10(x: Base?) { + when (x) { + is Base.A -> "" + else -> "" + } +} + +fun test_11(x: IBase?) { + when (x) { + is IBase.A -> "" + else -> "" + } +} + +fun test_12(x: Boolean?) { + when (x) { + true -> "" + else -> "" + } +} + +// ------------------ exhaustive ------------------ + +fun test_13(x: SomeEnum?) { + when (x) { + SomeEnum.A -> "" + SomeEnum.B -> "" + null -> "" + } +} + +fun test_14(x: Base?) { + when (x) { + is Base.A -> "" + is Base.B -> "" + null -> "" + } +} + +fun test_15(x: IBase?) { + when (x) { + is IBase.A -> "" + is IBase.B -> "" + null -> "" + } +} + +fun test_16(x: Boolean?) { + when (x) { + true -> "" + false -> "" + null -> "" + } +} diff --git a/compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_7.txt b/compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_7.txt new file mode 100644 index 00000000000..4357927d632 --- /dev/null +++ b/compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_7.txt @@ -0,0 +1,78 @@ +package + +public fun test_1(/*0*/ x: SomeEnum): kotlin.Unit +public fun test_10(/*0*/ x: Base?): kotlin.Unit +public fun test_11(/*0*/ x: IBase?): kotlin.Unit +public fun test_12(/*0*/ x: kotlin.Boolean?): kotlin.Unit +public fun test_13(/*0*/ x: SomeEnum?): kotlin.Unit +public fun test_14(/*0*/ x: Base?): kotlin.Unit +public fun test_15(/*0*/ x: IBase?): kotlin.Unit +public fun test_16(/*0*/ x: kotlin.Boolean?): kotlin.Unit +public fun test_2(/*0*/ x: Base): kotlin.Unit +public fun test_3(/*0*/ x: IBase): kotlin.Unit +public fun test_4(/*0*/ x: kotlin.Boolean): kotlin.Unit +public fun test_5(/*0*/ x: SomeEnum?): kotlin.Unit +public fun test_6(/*0*/ x: Base?): kotlin.Unit +public fun test_7(/*0*/ x: IBase?): kotlin.Unit +public fun test_8(/*0*/ x: kotlin.Boolean?): kotlin.Unit +public fun test_9(/*0*/ x: SomeEnum?): kotlin.Unit + +public sealed class Base { + protected constructor Base() + 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 class A : Base { + public 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 class B : Base { + public constructor B() + 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 sealed interface IBase { + 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 interface A : IBase { + 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 interface B : IBase { + 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 enum class SomeEnum : kotlin.Enum { + enum entry A + + enum entry B + + private constructor SomeEnum() + public final override /*1*/ /*fake_override*/ val name: kotlin.String + public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SomeEnum): kotlin.Int + public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit + public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class! + public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): SomeEnum + public final /*synthesized*/ fun values(): kotlin.Array +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/when/kt10192.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/when/kt10192.fir.kt new file mode 100644 index 00000000000..695bbb0f36b --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/when/kt10192.fir.kt @@ -0,0 +1,20 @@ +fun test1() { + if (true) { + when (true) { + true -> println() + } + } else { + System.out?.println() // kotlin.Unit? + } +} + +fun test2() { + val mlist = arrayListOf("") + if (true) { + when (true) { + true -> println() + } + } else { + mlist.add("") // kotlin.Boolean + } +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/when/kt10192.kt b/compiler/testData/diagnostics/testsWithStdLib/when/kt10192.kt index 94efaad6dfd..44296b83419 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/when/kt10192.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/when/kt10192.kt @@ -1,7 +1,6 @@ -// FIR_IDENTICAL fun test1() { if (true) { - when (true) { + when (true) { true -> println() } } else { @@ -12,10 +11,10 @@ fun test1() { fun test2() { val mlist = arrayListOf("") if (true) { - when (true) { + when (true) { true -> println() } } else { mlist.add("") // kotlin.Boolean } -} \ No newline at end of file +} 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 9795a86529b..d202308f762 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 @@ -31777,6 +31777,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/when/NonExhaustiveWarningNull.kt"); } + @Test + @TestMetadata("nonExhaustiveWhenStatement_1_6.kt") + public void testNonExhaustiveWhenStatement_1_6() throws Exception { + runTest("compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_6.kt"); + } + + @Test + @TestMetadata("nonExhaustiveWhenStatement_1_7.kt") + public void testNonExhaustiveWhenStatement_1_7() throws Exception { + runTest("compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_7.kt"); + } + @Test @TestMetadata("NonExhaustiveWithNullabilityCheck.kt") public void testNonExhaustiveWithNullabilityCheck() throws Exception { diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/1.1.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/1.1.kt index 009ac9d7618..dcc80b91f6a 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/1.1.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/1.1.kt @@ -70,11 +70,11 @@ fun case_5(value_1: Int, value_2: Int, value_3: Boolean?) { false -> "2" null -> "3" } - value_1 == 5 -> when (value_3) { + value_1 == 5 -> when (value_3) { true -> "1" false -> "2" } - value_1 == 6 -> when (value_3) {} + value_1 == 6 -> when (value_3) {} } } diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-5/pos/1.1.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-5/pos/1.1.kt index 4d7b5add6cb..ecc3b820d94 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-5/pos/1.1.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-5/pos/1.1.kt @@ -61,21 +61,21 @@ fun case_5(value_1: Int, value_2: Int, value_3: Boolean?) { value_2 > 100 -> "2" else -> "3" } - 2 -> when (value_3) { + 2 -> when (value_3) { value_2 > 1000 -> "1" value_2 > 100 -> "2" } - 3 -> when (value_3) {} + 3 -> when (value_3) {} 4 -> when (value_3) { true -> "1" false -> "2" null -> "3" } - 5 -> when (value_3) { + 5 -> when (value_3) { true -> "1" false -> "2" } - 6 -> when (value_3) {} + 6 -> when (value_3) {} } } diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/1.2.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/1.2.kt index 4dff73eb9f7..5d742231c96 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/1.2.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/1.2.kt @@ -41,7 +41,7 @@ fun case_3(value_1: SealedClass?): String = when (value_1) { * ISSUES: KT-22996 */ fun case_4(value_1: SealedClass?) { - when (value_1) { + when (value_1) { !is SealedChild2 -> {} // including null is SealedChild2? -> {} // redundant nullable type check } diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/5.1.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/5.1.kt index 6c1dee6db45..0d205b1b461 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/5.1.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/5.1.kt @@ -33,7 +33,7 @@ fun case_2(value_1: Number, value_2: Int) { // TESTCASE NUMBER: 3 fun case_3(value_1: Boolean, value_2: Boolean, value_3: Long) { - when (value_1) { + when (value_1) { value_2 -> {} !value_2 -> {} getBoolean() && value_2 -> {} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/5.2.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/5.2.kt index 66104fd2500..2be65d181ad 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/5.2.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/5.2.kt @@ -27,7 +27,7 @@ fun case_2(value_1: Number, value_2: Int) { // TESTCASE NUMBER: 3 fun case_3(value_1: Boolean, value_2: Boolean, value_3: Long) { - when (value_1) { + when (value_1) { value_2, !value_2, getBoolean() && value_2, getChar() != 'a' -> {} getList() === getAny(), value_3 <= 11 -> {} } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/controlFlow/initialization/neg/3.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/controlFlow/initialization/neg/3.kt index 6a6df57003e..b26d4a81172 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/controlFlow/initialization/neg/3.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/controlFlow/initialization/neg/3.kt @@ -15,7 +15,7 @@ fun case_1(value_1: EnumClass?) { val value_2: Int - when (value_1) { + when (value_1) { EnumClass.NORTH -> funWithExactlyOnceCallsInPlace { value_2 = 1 } EnumClass.SOUTH -> funWithExactlyOnceCallsInPlace { value_2 = 2 } EnumClass.EAST -> funWithExactlyOnceCallsInPlace { value_2 = 4 } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/8.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/8.kt index ebb360f8c21..c24c79bf9c0 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/8.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/8.kt @@ -109,7 +109,7 @@ fun case_4(value_1: Number, value_2: (() -> Unit)?) { // TESTCASE NUMBER: 5 fun case_5(value_1: Number?, value_2: String?) { - when (value_2.case_5(value_1)) { + when (value_2.case_5(value_1)) { true -> { println(value_2.length) println(value_1.toByte()) diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/8.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/8.kt index 8a04859367b..9af0bb16713 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/8.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/8.kt @@ -114,7 +114,7 @@ fun case_4(value_1: Number, value_2: (() -> Unit)?) { * ISSUES: KT-26612 */ fun case_5(value_1: Number?, value_2: String?) { - when (value_2.case_5(value_1)) { + when (value_2.case_5(value_1)) { true -> { println(value_2.length) println(value_1.toByte()) diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/54.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/54.kt index c5e771de2d6..677459a48ea 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/54.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/54.kt @@ -146,7 +146,7 @@ fun case_7() { var b = a b b.length - when (true) { + when (true) { true -> b = a } diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index 48ee875b965..59e224d537c 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -216,6 +216,10 @@ enum class LanguageFeature( TypeInferenceOnCallsWithSelfTypes(KOTLIN_1_6), OptInRelease(KOTLIN_1_6), + // 1.7 + + ProhibitNonExhaustiveWhenOnAlgebraicTypes(KOTLIN_1_7, kind = BUG_FIX), + // Temporarily disabled, see KT-27084/KT-22379 SoundSmartcastFromLoopConditionForLoopAssignedVariables(sinceVersion = null, kind = BUG_FIX), 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 db6e52a0109..473c4a61085 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 @@ -31681,6 +31681,18 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/when/NonExhaustiveWarningNull.kt"); } + @Test + @TestMetadata("nonExhaustiveWhenStatement_1_6.kt") + public void testNonExhaustiveWhenStatement_1_6() throws Exception { + runTest("compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_6.kt"); + } + + @Test + @TestMetadata("nonExhaustiveWhenStatement_1_7.kt") + public void testNonExhaustiveWhenStatement_1_7() throws Exception { + runTest("compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_7.kt"); + } + @Test @TestMetadata("NonExhaustiveWithNullabilityCheck.kt") public void testNonExhaustiveWithNullabilityCheck() throws Exception {