Fix resolve of last destructuring declaration in block

Last declaration in block is resolved in DEPENDENT mode because it has
 influence on return type and therefore fake call for destructuring declaration
 wasn't completed (see `getBlockReturnedTypeWithWritableScope`)

 Now we resolve fake call for destructuring declaration in INDEPENDENT
 mode as it doesn't have effect on return type

 #KT-15480 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2017-05-04 15:12:21 +03:00
parent 7530a9426f
commit adb8e60615
5 changed files with 52 additions and 3 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DataClassDescriptorResolver
import org.jetbrains.kotlin.resolve.LocalVariableResolver
import org.jetbrains.kotlin.resolve.TypeResolver
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
@@ -84,8 +85,9 @@ class DestructuringDeclarationResolver(
if (receiver == null) return errorType()
val expectedType = getExpectedTypeForComponent(context, entry)
val newContext = context.replaceExpectedType(expectedType).replaceContextDependency(ContextDependency.INDEPENDENT)
val results = fakeCallResolver.resolveFakeCall(
context.replaceExpectedType(expectedType), receiver, componentName,
newContext, receiver, componentName,
entry, initializer ?: entry, FakeCallKind.COMPONENT, emptyList()
)
@@ -0,0 +1,30 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE, -UNUSED_PARAMETER
fun test(list: A) {
if (true) {
val (c) = list
}
else {}
if (true) {
Unit
val (c) = list
}
else {}
when (1) {
1 -> {
val (c) = list
}
}
fn { it ->
val (a) = it
}
}
class A {
operator fun component1() = 1
}
fun fn(x: (A) -> Unit) {}
@@ -0,0 +1,12 @@
package
public fun fn(/*0*/ x: (A) -> kotlin.Unit): kotlin.Unit
public fun test(/*0*/ list: A): kotlin.Unit
public final class A {
public constructor A()
public final operator fun component1(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -5652,6 +5652,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("lastDestructuringDeclarationInBlock.kt")
public void testLastDestructuringDeclarationInBlock() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/declarationChecks/destructuringDeclarations/lastDestructuringDeclarationInBlock.kt");
doTest(fileName);
}
@TestMetadata("RedeclarationInForLoop.kt")
public void testRedeclarationInForLoop() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/declarationChecks/destructuringDeclarations/RedeclarationInForLoop.kt");
@@ -59,5 +59,4 @@ public class OutputPrefixPostfixTestGenerated extends AbstractOutputPrefixPostfi
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/outputPrefixPostfix/simpleWithPrefixAndPostfix.kt");
doTest(fileName);
}
}