Pattern matching: work-around for smart cast target type instability #KT-14705 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
bc0550d7b7
commit
b53ebd115b
+9
-9
@@ -245,15 +245,6 @@ class PatternMatchingTypingVisitor internal constructor(facade: ExpressionTyping
|
||||
possibleTypesForSubject: Set<KotlinType>
|
||||
) {
|
||||
val subjectExpression = expression.subjectExpression ?: return
|
||||
val isNullableType = TypeUtils.isNullableType(subjectType)
|
||||
val bindingContext = contextBeforeSubject.trace.bindingContext
|
||||
if (isNullableType && !WhenChecker.containsNullCase(expression, bindingContext)) {
|
||||
val notNullableType = TypeUtils.makeNotNullable(subjectType)
|
||||
if (checkSmartCastToExpectedTypeInSubject(contextBeforeSubject, subjectExpression, subjectType,
|
||||
notNullableType)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
for (possibleCastType in possibleTypesForSubject) {
|
||||
val possibleCastClass = possibleCastType.constructor.declarationDescriptor as? ClassDescriptor ?: continue
|
||||
if (possibleCastClass.kind == ClassKind.ENUM_CLASS || possibleCastClass.modality == Modality.SEALED) {
|
||||
@@ -263,6 +254,15 @@ class PatternMatchingTypingVisitor internal constructor(facade: ExpressionTyping
|
||||
}
|
||||
}
|
||||
}
|
||||
val isNullableType = TypeUtils.isNullableType(subjectType)
|
||||
val bindingContext = contextBeforeSubject.trace.bindingContext
|
||||
if (isNullableType && !WhenChecker.containsNullCase(expression, bindingContext)) {
|
||||
val notNullableType = TypeUtils.makeNotNullable(subjectType)
|
||||
if (checkSmartCastToExpectedTypeInSubject(contextBeforeSubject, subjectExpression, subjectType,
|
||||
notNullableType)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSmartCastToExpectedTypeInSubject(
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package test2
|
||||
|
||||
<info descr="null">enum</info> class En { A, B, С }
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val en2: Any? = En.A
|
||||
if (en2 is En) {
|
||||
when (<info descr="Smart cast to test2.En">en2</info>) {
|
||||
En.A -> {}
|
||||
En.B -> {}
|
||||
En.С -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -917,6 +917,12 @@ public class PsiCheckerTestGenerated extends AbstractPsiCheckerTest {
|
||||
doTestWithInfos(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("SmartCastToEnum.kt")
|
||||
public void testSmartCastToEnum() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/infos/SmartCastToEnum.kt");
|
||||
doTestWithInfos(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("SmartCasts.kt")
|
||||
public void testSmartCasts() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/infos/SmartCasts.kt");
|
||||
|
||||
Reference in New Issue
Block a user