[FIR] Fix exhaustiveness checking for conditions with equals to object
#KT-37488 Fixed
This commit is contained in:
+10
-2
@@ -149,8 +149,16 @@ class FirWhenExhaustivenessTransformer(private val bodyResolveComponents: BodyRe
|
||||
override fun visitOperatorCall(operatorCall: FirOperatorCall, data: SealedExhaustivenessData) {
|
||||
if (operatorCall.operation == FirOperation.EQ) {
|
||||
val argument = operatorCall.arguments[1]
|
||||
if (argument is FirConstExpression<*> && argument.value == null) {
|
||||
data.containsNull = true
|
||||
when (argument) {
|
||||
is FirConstExpression<*> -> {
|
||||
if (argument.value == null) {
|
||||
data.containsNull = true
|
||||
}
|
||||
}
|
||||
|
||||
is FirResolvedQualifier -> {
|
||||
argument.typeRef.accept(this, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// ISSUE: KT-37488
|
||||
|
||||
sealed class A
|
||||
|
||||
class B : A()
|
||||
object C : A()
|
||||
|
||||
fun takeString(s: String) {}
|
||||
|
||||
fun test_1(a: A) {
|
||||
val s = when(a) {
|
||||
is B -> ""
|
||||
is C -> ""
|
||||
}
|
||||
takeString(s)
|
||||
}
|
||||
|
||||
fun test_2(a: A) {
|
||||
val s = when(a) {
|
||||
is B -> ""
|
||||
C -> ""
|
||||
}
|
||||
takeString(s)
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
FILE: exhaustiveness_sealedObject.kt
|
||||
public sealed class A : R|kotlin/Any| {
|
||||
private constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final class B : R|A| {
|
||||
public constructor(): R|B| {
|
||||
super<R|A|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final object C : R|A| {
|
||||
private constructor(): R|C| {
|
||||
super<R|A|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final fun takeString(s: R|kotlin/String|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun test_1(a: R|A|): R|kotlin/Unit| {
|
||||
lval s: R|kotlin/String| = when (R|<local>/a|) {
|
||||
($subj$ is R|B|) -> {
|
||||
String()
|
||||
}
|
||||
($subj$ is R|C|) -> {
|
||||
String()
|
||||
}
|
||||
}
|
||||
|
||||
R|/takeString|(R|<local>/s|)
|
||||
}
|
||||
public final fun test_2(a: R|A|): R|kotlin/Unit| {
|
||||
lval s: R|kotlin/String| = when (R|<local>/a|) {
|
||||
($subj$ is R|B|) -> {
|
||||
String()
|
||||
}
|
||||
==($subj$, Q|C|) -> {
|
||||
String()
|
||||
}
|
||||
}
|
||||
|
||||
R|/takeString|(R|<local>/s|)
|
||||
}
|
||||
+5
@@ -138,6 +138,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
||||
runTest("compiler/fir/resolve/testData/resolve/exhaustiveness_sealedClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("exhaustiveness_sealedObject.kt")
|
||||
public void testExhaustiveness_sealedObject() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/exhaustiveness_sealedObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extension.kt")
|
||||
public void testExtension() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/extension.kt");
|
||||
|
||||
Generated
+5
@@ -138,6 +138,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
||||
runTest("compiler/fir/resolve/testData/resolve/exhaustiveness_sealedClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("exhaustiveness_sealedObject.kt")
|
||||
public void testExhaustiveness_sealedObject() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/exhaustiveness_sealedObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extension.kt")
|
||||
public void testExtension() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/extension.kt");
|
||||
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
sealed class Sealed {
|
||||
object First: Sealed()
|
||||
sealed class NonFirst {
|
||||
object Second: NonFirst()
|
||||
object Third: NonFirst()
|
||||
object Fourth: Sealed()
|
||||
}
|
||||
}
|
||||
|
||||
fun foo(s: Sealed, nf: Sealed.NonFirst): Int {
|
||||
val si = when(s) {
|
||||
Sealed.First -> 1
|
||||
Sealed.NonFirst.Fourth -> 4
|
||||
}
|
||||
val nfi = when(nf) {
|
||||
Sealed.NonFirst.Second -> 2
|
||||
Sealed.NonFirst.Third -> 3
|
||||
}
|
||||
return si <!UNRESOLVED_REFERENCE!>+<!> nfi
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
sealed class Sealed {
|
||||
object First: Sealed()
|
||||
sealed class NonFirst {
|
||||
|
||||
Reference in New Issue
Block a user