K2: Resolve non-exhaustive when expressions independently
^KT-55169 Fixed ^KT-55175 Related
This commit is contained in:
committed by
Space Team
parent
9fa0f51a61
commit
04d3996e68
+6
@@ -35152,6 +35152,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
||||
runTest("compiler/testData/diagnostics/tests/when/NonExhaustiveBooleanNullable.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nonExhaustiveDependentContext.kt")
|
||||
public void testNonExhaustiveDependentContext() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/when/nonExhaustiveDependentContext.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("NonExhaustivePlatformEnum.kt")
|
||||
public void testNonExhaustivePlatformEnum() throws Exception {
|
||||
|
||||
+6
@@ -35248,6 +35248,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/when/NonExhaustiveBooleanNullable.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nonExhaustiveDependentContext.kt")
|
||||
public void testNonExhaustiveDependentContext() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/when/nonExhaustiveDependentContext.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("NonExhaustivePlatformEnum.kt")
|
||||
public void testNonExhaustivePlatformEnum() throws Exception {
|
||||
|
||||
+6
@@ -35152,6 +35152,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/when/NonExhaustiveBooleanNullable.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nonExhaustiveDependentContext.kt")
|
||||
public void testNonExhaustiveDependentContext() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/when/nonExhaustiveDependentContext.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("NonExhaustivePlatformEnum.kt")
|
||||
public void testNonExhaustivePlatformEnum() throws Exception {
|
||||
|
||||
+3
@@ -91,6 +91,9 @@ class FirWhenExhaustivenessTransformer(private val bodyResolveComponents: BodyRe
|
||||
throw IllegalArgumentException("Should not be there")
|
||||
}
|
||||
|
||||
/**
|
||||
* The synthetic call for the whole [whenExpression] might be not completed yet
|
||||
*/
|
||||
override fun transformWhenExpression(whenExpression: FirWhenExpression, data: Any?): FirStatement {
|
||||
processExhaustivenessCheck(whenExpression)
|
||||
bodyResolveComponents.session.enumWhenTracker?.reportEnumUsageInWhen(
|
||||
|
||||
+25
-5
@@ -64,7 +64,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes
|
||||
@Suppress("NAME_SHADOWING")
|
||||
var whenExpression = whenExpression.transformSubject(transformer, ResolutionMode.ContextIndependent)
|
||||
val subjectType = whenExpression.subject?.typeRef?.coneType?.fullyExpandedType(session)
|
||||
var callCompleted = false
|
||||
var completionNeeded = false
|
||||
context.withWhenSubjectType(subjectType, components) {
|
||||
when {
|
||||
whenExpression.branches.isEmpty() -> {}
|
||||
@@ -78,19 +78,39 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes
|
||||
|
||||
whenExpression = syntheticCallGenerator.generateCalleeForWhenExpression(whenExpression, resolutionContext) ?: run {
|
||||
whenExpression = whenExpression.transformSingle(whenExhaustivenessTransformer, null)
|
||||
dataFlowAnalyzer.exitWhenExpression(whenExpression, callCompleted)
|
||||
dataFlowAnalyzer.exitWhenExpression(whenExpression, callCompleted = false)
|
||||
whenExpression.resultType = buildErrorTypeRef {
|
||||
diagnostic = ConeSimpleDiagnostic("Can't resolve when expression", DiagnosticKind.InferenceError)
|
||||
}
|
||||
return@withWhenSubjectType whenExpression
|
||||
}
|
||||
|
||||
val completionResult = callCompleter.completeCall(whenExpression, data)
|
||||
whenExpression = completionResult.result
|
||||
callCompleted = completionResult.callCompleted
|
||||
completionNeeded = true
|
||||
}
|
||||
}
|
||||
whenExpression = whenExpression.transformSingle(whenExhaustivenessTransformer, null)
|
||||
|
||||
// This is necessary to perform outside the place where the synthetic call is created because
|
||||
// exhaustiveness is not yet computed there, but at the same time to compute it properly
|
||||
// we need having branches condition bes analyzed that is why we can't have call
|
||||
// `whenExpression.transformSingle(whenExhaustivenessTransformer, null)` at the beginning
|
||||
val callCompleted = when {
|
||||
completionNeeded -> {
|
||||
val completionResult = callCompleter.completeCall(
|
||||
whenExpression,
|
||||
// For non-exhaustive when expressions, we should complete then as independent because below
|
||||
// their type is artificially replaced with Unit, while candidate symbol's return type remains the same
|
||||
// So when combining two when's the inner one was erroneously resolved as a normal dependent exhaustive sub-expression
|
||||
// At the same time, it all looks suspicious and inconsistent, so we hope it would be investigated at KT-55175
|
||||
if (whenExpression.isProperlyExhaustive) data else ResolutionMode.ContextIndependent,
|
||||
)
|
||||
whenExpression = completionResult.result
|
||||
|
||||
completionResult.callCompleted
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
|
||||
dataFlowAnalyzer.exitWhenExpression(whenExpression, callCompleted)
|
||||
whenExpression = whenExpression.replaceReturnTypeIfNotExhaustive()
|
||||
whenExpression
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// SKIP_TXT
|
||||
fun bar(a: String): String {
|
||||
return <!RETURN_TYPE_MISMATCH!>when {
|
||||
a.length == 1 -> {
|
||||
when { // Error in K1, no error in K2
|
||||
a == "a" -> ""
|
||||
a == "b" -> ""
|
||||
}
|
||||
}
|
||||
|
||||
else -> ""
|
||||
}<!>
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// SKIP_TXT
|
||||
fun bar(a: String): String {
|
||||
return when {
|
||||
a.length == 1 -> {
|
||||
<!NO_ELSE_IN_WHEN!>when<!> { // Error in K1, no error in K2
|
||||
a == "a" -> ""
|
||||
a == "b" -> ""
|
||||
}
|
||||
}
|
||||
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
Generated
+6
@@ -35248,6 +35248,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/when/NonExhaustiveBooleanNullable.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nonExhaustiveDependentContext.kt")
|
||||
public void testNonExhaustiveDependentContext() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/when/nonExhaustiveDependentContext.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("NonExhaustivePlatformEnum.kt")
|
||||
public void testNonExhaustivePlatformEnum() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user