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>
|
possibleTypesForSubject: Set<KotlinType>
|
||||||
) {
|
) {
|
||||||
val subjectExpression = expression.subjectExpression ?: return
|
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) {
|
for (possibleCastType in possibleTypesForSubject) {
|
||||||
val possibleCastClass = possibleCastType.constructor.declarationDescriptor as? ClassDescriptor ?: continue
|
val possibleCastClass = possibleCastType.constructor.declarationDescriptor as? ClassDescriptor ?: continue
|
||||||
if (possibleCastClass.kind == ClassKind.ENUM_CLASS || possibleCastClass.modality == Modality.SEALED) {
|
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(
|
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);
|
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")
|
@TestMetadata("SmartCasts.kt")
|
||||||
public void testSmartCasts() throws Exception {
|
public void testSmartCasts() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/infos/SmartCasts.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/infos/SmartCasts.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user