Solution for KT-7838: now data flow information at the end of when expression is determined correctly.
#KT-7838 Fixed.
This commit is contained in:
+5
@@ -130,6 +130,11 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
||||
if (commonDataFlowInfo == null) {
|
||||
commonDataFlowInfo = context.dataFlowInfo;
|
||||
}
|
||||
else if (expression.getElseExpression() == null && !WhenChecker.isWhenExhaustive(expression, context.trace)) {
|
||||
// Without else expression in non-exhaustive when, we *must* take initial data flow info into account,
|
||||
// because data flow can bypass all when branches in this case
|
||||
commonDataFlowInfo = commonDataFlowInfo.or(context.dataFlowInfo);
|
||||
}
|
||||
|
||||
return TypeInfoFactoryPackage.createTypeInfo(expressionTypes.isEmpty() ? null : DataFlowUtils.checkType(
|
||||
DataFlowUtils.checkImplicitCast(
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
class A
|
||||
|
||||
fun test(a: Any): String {
|
||||
val q: String? = null
|
||||
|
||||
when (a) {
|
||||
is A -> q!!
|
||||
}
|
||||
// When is not exhaustive
|
||||
return <!TYPE_MISMATCH!>q<!>
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package
|
||||
|
||||
internal fun test(/*0*/ a: kotlin.Any): kotlin.String
|
||||
|
||||
internal final class A {
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class A
|
||||
|
||||
fun test(a: Any) {
|
||||
var q: String? = null
|
||||
|
||||
when (a) {
|
||||
is A -> q = "1"
|
||||
}
|
||||
// When is not exhaustive
|
||||
return <!TYPE_MISMATCH!>q<!>
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package
|
||||
|
||||
internal fun test(/*0*/ a: kotlin.Any): kotlin.Unit
|
||||
|
||||
internal final class A {
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
enum class My { A, B }
|
||||
|
||||
fun test(a: My): String {
|
||||
val q: String?
|
||||
|
||||
when (a) {
|
||||
My.A -> q = "1"
|
||||
My.B -> q = "2"
|
||||
}
|
||||
// When is exhaustive
|
||||
return <!DEBUG_INFO_SMARTCAST!>q<!>
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package
|
||||
|
||||
internal fun test(/*0*/ a: My): kotlin.String
|
||||
|
||||
internal final enum class My : kotlin.Enum<My> {
|
||||
public enum entry A : My {
|
||||
private constructor A()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: My): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public enum entry B : My {
|
||||
private constructor B()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: My): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
private constructor My()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: My): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): My
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<My>
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
class A
|
||||
|
||||
fun test(a: Any): String {
|
||||
var q: String?
|
||||
|
||||
when (a) {
|
||||
is A -> q = "1"
|
||||
else -> q = "2"
|
||||
}
|
||||
// When is not exhaustive
|
||||
return <!DEBUG_INFO_SMARTCAST!>q<!>
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package
|
||||
|
||||
internal fun test(/*0*/ a: kotlin.Any): kotlin.String
|
||||
|
||||
internal final class A {
|
||||
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
|
||||
}
|
||||
@@ -13548,6 +13548,30 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("BranchBypassVal.kt")
|
||||
public void testBranchBypassVal() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/when/BranchBypassVal.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("BranchBypassVar.kt")
|
||||
public void testBranchBypassVar() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/when/BranchBypassVar.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("BranchFalseBypass.kt")
|
||||
public void testBranchFalseBypass() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/when/BranchFalseBypass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("BranchFalseBypassElse.kt")
|
||||
public void testBranchFalseBypassElse() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/when/BranchFalseBypassElse.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ElseOnNullableEnum.kt")
|
||||
public void testElseOnNullableEnum() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/when/ElseOnNullableEnum.kt");
|
||||
|
||||
Reference in New Issue
Block a user