[FIR] Fix local RETURN_TYPE_MISMATCH with flexible Unit and multiple Unit returns

This commit is contained in:
Ivan Kochurkin
2023-09-20 15:02:46 +02:00
committed by Space Team
parent 4b9e15dfa8
commit b5acd1da6a
8 changed files with 97 additions and 3 deletions
@@ -13433,6 +13433,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/LocalReturnWithExplicitUnit.kt");
}
@Test
@TestMetadata("LocalReturnWithFlexibleUnitType.kt")
public void testLocalReturnWithFlexibleUnitType() throws Exception {
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/LocalReturnWithFlexibleUnitType.kt");
}
@Test
@TestMetadata("LocalReturnsWithExplicitReturnType.kt")
public void testLocalReturnsWithExplicitReturnType() throws Exception {
@@ -13445,6 +13451,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/MixedReturnsFromLambda.kt");
}
@Test
@TestMetadata("MultipleLocalUnitReturns.kt")
public void testMultipleLocalUnitReturns() throws Exception {
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/MultipleLocalUnitReturns.kt");
}
@Test
@TestMetadata("NoCommonSystem.kt")
public void testNoCommonSystem() throws Exception {
@@ -13433,6 +13433,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/LocalReturnWithExplicitUnit.kt");
}
@Test
@TestMetadata("LocalReturnWithFlexibleUnitType.kt")
public void testLocalReturnWithFlexibleUnitType() throws Exception {
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/LocalReturnWithFlexibleUnitType.kt");
}
@Test
@TestMetadata("LocalReturnsWithExplicitReturnType.kt")
public void testLocalReturnsWithExplicitReturnType() throws Exception {
@@ -13445,6 +13451,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/MixedReturnsFromLambda.kt");
}
@Test
@TestMetadata("MultipleLocalUnitReturns.kt")
public void testMultipleLocalUnitReturns() throws Exception {
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/MultipleLocalUnitReturns.kt");
}
@Test
@TestMetadata("NoCommonSystem.kt")
public void testNoCommonSystem() throws Exception {
@@ -13433,6 +13433,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/LocalReturnWithExplicitUnit.kt");
}
@Test
@TestMetadata("LocalReturnWithFlexibleUnitType.kt")
public void testLocalReturnWithFlexibleUnitType() throws Exception {
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/LocalReturnWithFlexibleUnitType.kt");
}
@Test
@TestMetadata("LocalReturnsWithExplicitReturnType.kt")
public void testLocalReturnsWithExplicitReturnType() throws Exception {
@@ -13445,6 +13451,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/MixedReturnsFromLambda.kt");
}
@Test
@TestMetadata("MultipleLocalUnitReturns.kt")
public void testMultipleLocalUnitReturns() throws Exception {
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/MultipleLocalUnitReturns.kt");
}
@Test
@TestMetadata("NoCommonSystem.kt")
public void testNoCommonSystem() throws Exception {
@@ -13439,6 +13439,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/LocalReturnWithExplicitUnit.kt");
}
@Test
@TestMetadata("LocalReturnWithFlexibleUnitType.kt")
public void testLocalReturnWithFlexibleUnitType() throws Exception {
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/LocalReturnWithFlexibleUnitType.kt");
}
@Test
@TestMetadata("LocalReturnsWithExplicitReturnType.kt")
public void testLocalReturnsWithExplicitReturnType() throws Exception {
@@ -13451,6 +13457,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/MixedReturnsFromLambda.kt");
}
@Test
@TestMetadata("MultipleLocalUnitReturns.kt")
public void testMultipleLocalUnitReturns() throws Exception {
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/MultipleLocalUnitReturns.kt");
}
@Test
@TestMetadata("NoCommonSystem.kt")
public void testNoCommonSystem() throws Exception {
@@ -91,7 +91,7 @@ object FirFunctionReturnTypeMismatchChecker : FirReturnExpressionChecker() {
}
}
} else if (resultExpression.source?.kind is KtFakeSourceElementKind.ImplicitUnit &&
!functionReturnType.isUnit &&
!functionReturnType.lowerBoundIfFlexible().isUnit &&
shouldCheckMismatchForAnonymousFunction(targetElement, expression)
) {
// Disallow cases like
@@ -120,8 +120,11 @@ object FirFunctionReturnTypeMismatchChecker : FirReturnExpressionChecker() {
private fun shouldCheckMismatchForAnonymousFunction(targetElement: FirFunction, expression: FirReturnExpression): Boolean {
if (targetElement !is FirAnonymousFunction || !targetElement.isLambda) return true
val cfgNodes = targetElement.controlFlowGraphReference?.controlFlowGraph?.exitNode?.previousCfgNodes ?: return true
// Check if any return expression other than the current is explicit
return cfgNodes.any { if (it.fir === expression) false else it.fir is FirReturnExpression }
// Check if any return expression other than the current is explicit and not Unit
return cfgNodes.any {
val fir = it.fir
if (fir === expression) false else fir is FirReturnExpression && !fir.result.resolvedType.isUnit
}
}
}
@@ -0,0 +1,20 @@
// FIR_IDENTICAL
// FILE: JavaClass.java
@FunctionalInterface
public interface JavaClass<T> {
public T invoke();
}
// FILE: main.kt
fun main() {
JavaClass {
if (true) {
return@JavaClass
} else {
return@JavaClass
}
}
}
@@ -0,0 +1,11 @@
// FIR_IDENTICAL
fun <T> execute(block: () -> T): T = block()
fun main() {
execute {
if (true) return@execute
if (true) return@execute Unit
execute { Any() }
}
}
@@ -13439,6 +13439,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/LocalReturnWithExplicitUnit.kt");
}
@Test
@TestMetadata("LocalReturnWithFlexibleUnitType.kt")
public void testLocalReturnWithFlexibleUnitType() throws Exception {
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/LocalReturnWithFlexibleUnitType.kt");
}
@Test
@TestMetadata("LocalReturnsWithExplicitReturnType.kt")
public void testLocalReturnsWithExplicitReturnType() throws Exception {
@@ -13451,6 +13457,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/MixedReturnsFromLambda.kt");
}
@Test
@TestMetadata("MultipleLocalUnitReturns.kt")
public void testMultipleLocalUnitReturns() throws Exception {
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/MultipleLocalUnitReturns.kt");
}
@Test
@TestMetadata("NoCommonSystem.kt")
public void testNoCommonSystem() throws Exception {