diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt index e802defef3c..1dd91411ec6 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt @@ -92,12 +92,17 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre ) } // Necessary for local functions - ForceResolveUtil.forceResolveAllContents(functionDescriptor.annotations); + ForceResolveUtil.forceResolveAllContents(functionDescriptor.annotations) - val functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace) - components.expressionTypingServices.checkFunctionReturnType( - functionInnerScope, function, functionDescriptor, context.dataFlowInfo, null, context.trace - ) + if (!function.hasDeclaredReturnType() && !function.hasBlockBody()) { + ForceResolveUtil.forceResolveAllContents(functionDescriptor.returnType) + } + else { + val functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace) + components.expressionTypingServices.checkFunctionReturnType( + functionInnerScope, function, functionDescriptor, context.dataFlowInfo, null, context.trace + ) + } components.valueParameterResolver.resolveValueParameters( function.getValueParameters(), functionDescriptor.valueParameters, context.scope, context.dataFlowInfo, context.trace diff --git a/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/localFactorial.kt b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/localFactorial.kt new file mode 100644 index 00000000000..6213b43563d --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/localFactorial.kt @@ -0,0 +1,11 @@ +// See KT-6271 +fun foo() { + fun fact(n: Int) = { + if (n > 0) { + fact(n - 1) * n + } + else { + 1 + } + } +} diff --git a/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/localFactorial.txt b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/localFactorial.txt new file mode 100644 index 00000000000..65a6ac47e1f --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/localFactorial.txt @@ -0,0 +1,3 @@ +package + +public fun foo(): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveFun.kt b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveFun.kt new file mode 100644 index 00000000000..bd777a778b3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveFun.kt @@ -0,0 +1,3 @@ +fun foo() { + fun bar() = (fun() = bar()) +} diff --git a/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveFun.txt b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveFun.txt new file mode 100644 index 00000000000..65a6ac47e1f --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveFun.txt @@ -0,0 +1,3 @@ +package + +public fun foo(): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveLambda.kt b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveLambda.kt new file mode 100644 index 00000000000..016f29e7f66 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveLambda.kt @@ -0,0 +1,5 @@ +fun foo() { + fun bar() = { + bar() + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveLambda.txt b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveLambda.txt new file mode 100644 index 00000000000..65a6ac47e1f --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveLambda.txt @@ -0,0 +1,3 @@ +package + +public fun foo(): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/selfCall.kt b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/selfCall.kt new file mode 100644 index 00000000000..a37cd9f43a7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/selfCall.kt @@ -0,0 +1,8 @@ +fun foo() { + fun bar1() = bar1() + + fun bar2() = 1 + bar2() + fun bar3() = id(bar3()) +} + +fun id(x: T) = x diff --git a/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/selfCall.txt b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/selfCall.txt new file mode 100644 index 00000000000..8e92243886c --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/selfCall.txt @@ -0,0 +1,4 @@ +package + +public fun foo(): kotlin.Unit +public fun id(/*0*/ x: T): T diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 6a21439115b..3ab54a0f3b6 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -8580,6 +8580,39 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { } } + @TestMetadata("compiler/testData/diagnostics/tests/inference/recursiveLocalFuns") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class RecursiveLocalFuns extends AbstractDiagnosticsTest { + public void testAllFilesPresentInRecursiveLocalFuns() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/recursiveLocalFuns"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("localFactorial.kt") + public void testLocalFactorial() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/localFactorial.kt"); + doTest(fileName); + } + + @TestMetadata("recursiveFun.kt") + public void testRecursiveFun() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveFun.kt"); + doTest(fileName); + } + + @TestMetadata("recursiveLambda.kt") + public void testRecursiveLambda() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveLambda.kt"); + doTest(fileName); + } + + @TestMetadata("selfCall.kt") + public void testSelfCall() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/selfCall.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/diagnostics/tests/inference/regressions") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)