KT-328 Local function in function literals cause exceptions

===
fun bar() = {
  bar()
}
===
This commit is contained in:
Stepan Koltsov
2011-11-23 16:40:50 +04:00
parent ba700ebdbe
commit e33af7f729
7 changed files with 40 additions and 13 deletions
@@ -82,7 +82,7 @@ public class BodyResolver {
resolveSecondaryConstructorBodies();
resolveFunctionBodies();
computeDeferredTypes();
computeDeferredTypes();
}
private void resolveDelegationSpecifierLists() {
@@ -501,6 +501,18 @@ public class BodyResolver {
for (Map.Entry<JetNamedFunction, FunctionDescriptorImpl> entry : this.context.getFunctions().entrySet()) {
JetNamedFunction declaration = entry.getKey();
FunctionDescriptor descriptor = entry.getValue();
if (descriptor.getReturnType() instanceof DeferredType) {
// handle type inference loop: function body contains a closure that calls that function
//
// fun f() = { f() }
//
// function type resolution must be started before function body resolution
//
DeferredType returnType = (DeferredType) descriptor.getReturnType();
returnType.getActualType();
}
JetScope declaringScope = this.context.getDeclaringScopes().get(declaration);
assert declaringScope != null;
@@ -545,7 +557,8 @@ public class BodyResolver {
private void computeDeferredTypes() {
Collection<Box<DeferredType>> deferredTypes = context.getTrace().getKeys(DEFERRED_TYPE);
if (deferredTypes != null) {
final Queue<DeferredType> queue = new Queue<DeferredType>(deferredTypes.size());
// +1 is a work around agains new Queue(0).addLast(...) bug // stepan.koltsov@ 2011-11-21
final Queue<DeferredType> queue = new Queue<DeferredType>(deferredTypes.size() + 1);
context.getTrace().addHandler(DEFERRED_TYPE, new ObservableBindingTrace.RecordHandler<Box<DeferredType>, Boolean>() {
@Override
public void handleRecord(WritableSlice<Box<DeferredType>, Boolean> deferredTypeKeyDeferredTypeWritableSlice, Box<DeferredType> key, Boolean value) {
@@ -222,6 +222,7 @@ public class DescriptorRenderer implements Renderer {
renderName(descriptor, builder);
renderValueParameters(descriptor, builder);
// TODO: getReturnType may be uninitialized and throw IllegalStateException // stepan.koltsov@ 2011-11-21
builder.append(" : ").append(escape(renderType(descriptor.getReturnType())));
return super.visitFunctionDescriptor(descriptor, builder);
}
@@ -5,15 +5,15 @@ namespace a {
}
namespace b {
fun foo() = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar()<!>
fun foo() = bar()
fun bar() = foo()
fun bar() = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>foo()<!>
}
namespace c {
fun bazz() = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar()<!>
fun bazz() = bar()
fun foo() = bazz()
fun foo() = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bazz()<!>
fun bar() = foo()
}
@@ -39,4 +39,4 @@ namespace ok {
fun bar() = foo()
}
}
}
@@ -0,0 +1,3 @@
fun bar() = {
<!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar()<!>
}
@@ -0,0 +1,3 @@
fun bar() = {
fun foo() = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar()<!>
}
@@ -0,0 +1,7 @@
// http://youtrack.jetbrains.net/issue/KT-329
fun block(f : fun() : Unit) = f()
fun bar() = block{ <!UNRESOLVED_REFERENCE!>foo<!>() // <-- missing closing curly bracket
fun foo() = block{ <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar()<!> }
@@ -1,19 +1,19 @@
namespace a {
val foo = <error>bar()</error>
val foo = <error descr="[TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM] Type checking has run into a recursive problem">bar()</error>
fun bar() = foo
}
namespace b {
fun foo() = <error>bar()</error>
fun foo() = bar()
fun bar() = foo()
fun bar() = <error descr="[TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM] Type checking has run into a recursive problem">foo()</error>
}
namespace c {
fun bazz() = <error>bar()</error>
fun bazz() = bar()
fun foo() = bazz()
fun foo() = <error descr="[TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM] Type checking has run into a recursive problem">bazz()</error>
fun bar() = foo()
}
@@ -39,4 +39,4 @@ namespace ok {
fun bar() = foo()
}
}
}