Force type calculation for local function if it should be inferred

It helps to catch TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM errors
because they appear after return type calculation began

 #KT-6271 Fixed
 #KT-3272 Obsolete
This commit is contained in:
Denis Zharkov
2016-01-28 17:39:49 +03:00
parent 7d6310d88c
commit 855a0b3493
10 changed files with 83 additions and 5 deletions
@@ -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
@@ -0,0 +1,11 @@
// See KT-6271
fun foo() {
fun fact(n: Int) = {
if (n > 0) {
<!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>fact(n - 1)<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>*<!> n
}
else {
1
}
}
}
@@ -0,0 +1,3 @@
package
public fun foo(): kotlin.Unit
@@ -0,0 +1,3 @@
fun foo() {
fun bar() = (fun() = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar()<!>)
}
@@ -0,0 +1,3 @@
package
public fun foo(): kotlin.Unit
@@ -0,0 +1,5 @@
fun foo() {
fun bar() = {
<!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar()<!>
}
}
@@ -0,0 +1,3 @@
package
public fun foo(): kotlin.Unit
@@ -0,0 +1,8 @@
fun foo() {
fun bar1() = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar1()<!>
fun bar2() = 1 + <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar2()<!>
fun bar3() = id(<!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar3()<!>)
}
fun <T> id(x: T) = x
@@ -0,0 +1,4 @@
package
public fun foo(): kotlin.Unit
public fun </*0*/ T> id(/*0*/ x: T): T
@@ -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)