KT-328 Local function in function literals cause exceptions
===
fun bar() = {
bar()
}
===
This commit is contained in:
@@ -82,7 +82,7 @@ public class BodyResolver {
|
|||||||
resolveSecondaryConstructorBodies();
|
resolveSecondaryConstructorBodies();
|
||||||
resolveFunctionBodies();
|
resolveFunctionBodies();
|
||||||
|
|
||||||
computeDeferredTypes();
|
computeDeferredTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resolveDelegationSpecifierLists() {
|
private void resolveDelegationSpecifierLists() {
|
||||||
@@ -501,6 +501,18 @@ public class BodyResolver {
|
|||||||
for (Map.Entry<JetNamedFunction, FunctionDescriptorImpl> entry : this.context.getFunctions().entrySet()) {
|
for (Map.Entry<JetNamedFunction, FunctionDescriptorImpl> entry : this.context.getFunctions().entrySet()) {
|
||||||
JetNamedFunction declaration = entry.getKey();
|
JetNamedFunction declaration = entry.getKey();
|
||||||
FunctionDescriptor descriptor = entry.getValue();
|
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);
|
JetScope declaringScope = this.context.getDeclaringScopes().get(declaration);
|
||||||
assert declaringScope != null;
|
assert declaringScope != null;
|
||||||
@@ -545,7 +557,8 @@ public class BodyResolver {
|
|||||||
private void computeDeferredTypes() {
|
private void computeDeferredTypes() {
|
||||||
Collection<Box<DeferredType>> deferredTypes = context.getTrace().getKeys(DEFERRED_TYPE);
|
Collection<Box<DeferredType>> deferredTypes = context.getTrace().getKeys(DEFERRED_TYPE);
|
||||||
if (deferredTypes != null) {
|
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>() {
|
context.getTrace().addHandler(DEFERRED_TYPE, new ObservableBindingTrace.RecordHandler<Box<DeferredType>, Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public void handleRecord(WritableSlice<Box<DeferredType>, Boolean> deferredTypeKeyDeferredTypeWritableSlice, Box<DeferredType> key, Boolean value) {
|
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);
|
renderName(descriptor, builder);
|
||||||
renderValueParameters(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())));
|
builder.append(" : ").append(escape(renderType(descriptor.getReturnType())));
|
||||||
return super.visitFunctionDescriptor(descriptor, builder);
|
return super.visitFunctionDescriptor(descriptor, builder);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,15 +5,15 @@ namespace a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace b {
|
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 {
|
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()
|
fun bar() = foo()
|
||||||
}
|
}
|
||||||
@@ -39,4 +39,4 @@ namespace ok {
|
|||||||
|
|
||||||
fun bar() = foo()
|
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 {
|
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
|
fun bar() = foo
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace b {
|
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 {
|
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()
|
fun bar() = foo()
|
||||||
}
|
}
|
||||||
@@ -39,4 +39,4 @@ namespace ok {
|
|||||||
|
|
||||||
fun bar() = foo()
|
fun bar() = foo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user