K2: Fix false-positive DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE
For explanation, see nestedPartiallyResolvedCallsSimple.k
The problem was caused by "select" variable is being leaked to the
inference session of delegate while it should not happen because
it doesn't belong to the common system of `KotlinVal { ..` call,
as we complete it with fixing `E` variable during completion
for `A(select(null, fun(): Int { return 1 }))`.
The root of the problem is that we were adding all the partial
nested calls to the session, while in fact we only need there
the top-level one.
^KT-57543 Fixed
This commit is contained in:
+12
@@ -8931,6 +8931,18 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
||||
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/manyIncompleteCandidates.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedPartiallyResolvedCalls.kt")
|
||||
public void testNestedPartiallyResolvedCalls() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/nestedPartiallyResolvedCalls.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedPartiallyResolvedCallsSimple.kt")
|
||||
public void testNestedPartiallyResolvedCallsSimple() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/nestedPartiallyResolvedCallsSimple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("noErrorsForImplicitConstraints.kt")
|
||||
public void testNoErrorsForImplicitConstraints() throws Exception {
|
||||
|
||||
+12
@@ -8931,6 +8931,18 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
||||
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/manyIncompleteCandidates.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedPartiallyResolvedCalls.kt")
|
||||
public void testNestedPartiallyResolvedCalls() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/nestedPartiallyResolvedCalls.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedPartiallyResolvedCallsSimple.kt")
|
||||
public void testNestedPartiallyResolvedCallsSimple() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/nestedPartiallyResolvedCallsSimple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("noErrorsForImplicitConstraints.kt")
|
||||
public void testNoErrorsForImplicitConstraints() throws Exception {
|
||||
|
||||
+12
@@ -8931,6 +8931,18 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/manyIncompleteCandidates.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedPartiallyResolvedCalls.kt")
|
||||
public void testNestedPartiallyResolvedCalls() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/nestedPartiallyResolvedCalls.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedPartiallyResolvedCallsSimple.kt")
|
||||
public void testNestedPartiallyResolvedCallsSimple() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/nestedPartiallyResolvedCallsSimple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("noErrorsForImplicitConstraints.kt")
|
||||
public void testNoErrorsForImplicitConstraints() throws Exception {
|
||||
|
||||
+12
@@ -8937,6 +8937,18 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/manyIncompleteCandidates.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedPartiallyResolvedCalls.kt")
|
||||
public void testNestedPartiallyResolvedCalls() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/nestedPartiallyResolvedCalls.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedPartiallyResolvedCallsSimple.kt")
|
||||
public void testNestedPartiallyResolvedCallsSimple() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/nestedPartiallyResolvedCallsSimple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("noErrorsForImplicitConstraints.kt")
|
||||
public void testNoErrorsForImplicitConstraints() throws Exception {
|
||||
|
||||
+5
-1
@@ -111,9 +111,13 @@ class FirCallCompleter(
|
||||
|
||||
ConstraintSystemCompletionMode.PARTIAL -> {
|
||||
runCompletionForCall(candidate, completionMode, call, initialType, analyzer)
|
||||
if (inferenceSession !is FirBuilderInferenceSession) {
|
||||
|
||||
// Add top-level delegate call as partially resolved to inference session
|
||||
if (resolutionMode is ResolutionMode.ContextDependentDelegate) {
|
||||
require(inferenceSession is FirDelegatedPropertyInferenceSession)
|
||||
inferenceSession.addPartiallyResolvedCall(call)
|
||||
}
|
||||
|
||||
CompletionResult(call, false)
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -318,8 +318,9 @@ open class FirDeclarationsResolveTransformer(
|
||||
wrappedDelegateExpression: FirWrappedDelegateExpression,
|
||||
data: ResolutionMode,
|
||||
): FirStatement {
|
||||
// First, resolve delegate expression in dependent context
|
||||
val delegateExpression = wrappedDelegateExpression.expression.transformSingle(transformer, ResolutionMode.ContextDependent)
|
||||
// First, resolve delegate expression in dependent context, and add potentially partially resolved call to inference session
|
||||
// (that is why we use ContextDependentDelegate instead of plain ContextDependent)
|
||||
val delegateExpression = wrappedDelegateExpression.expression.transformSingle(transformer, ResolutionMode.ContextDependentDelegate)
|
||||
.transformSingle(components.integerLiteralAndOperatorApproximationTransformer, null)
|
||||
|
||||
// Second, replace result type of delegate expression with stub type if delegate not yet resolved
|
||||
|
||||
compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.fir.kt
Vendored
+2
-2
@@ -9,8 +9,8 @@ class A(outer: Outer) {
|
||||
var g: String by outer.getContainer().getMyProperty()
|
||||
|
||||
|
||||
var b: String by <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>(<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>getMyProperty<!>())
|
||||
var r: String by <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>(outer.getContainer().<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>getMyProperty<!>())
|
||||
var b: String by <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>(getMyProperty())
|
||||
var r: String by <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>(outer.getContainer().getMyProperty())
|
||||
var e: String by + <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>(getMyProperty())
|
||||
var f: String by <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>(getMyProperty()) - 1
|
||||
}
|
||||
|
||||
Vendored
+34
@@ -0,0 +1,34 @@
|
||||
// FIR_IDENTICAL
|
||||
// WITH_STDLIB
|
||||
// ISSUE: KT-57543
|
||||
|
||||
// FILE: JavaClass.java
|
||||
import kotlin.jvm.functions.Function0;
|
||||
|
||||
public class JavaClass {
|
||||
|
||||
public static class Val<T> {
|
||||
private final Function0<T> initializer;
|
||||
public Val(Function0<T> initializer) {
|
||||
this.initializer = initializer;
|
||||
}
|
||||
public final T getValue(Object instance, Object metadata) {
|
||||
return initializer.invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> Val<T> lazySoft(Function0<T> initializer) {
|
||||
return new Val<T>(initializer);
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
class A(
|
||||
val c: Int? = 0,
|
||||
myType: (() -> Int)? = null
|
||||
) {
|
||||
val arguments: A by JavaClass.lazySoft {
|
||||
A(myType = if (false) null else fun(): Int { return c!! })
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// FIR_IDENTICAL
|
||||
// ISSUE: KT-57543
|
||||
|
||||
class KotlinVal<T>(initializer: () -> T) {
|
||||
operator fun getValue(instance: Any?, metadata: Any?): T = TODO()
|
||||
}
|
||||
|
||||
class A(
|
||||
myType: (() -> Int)?
|
||||
) {
|
||||
val arguments: A by KotlinVal {
|
||||
A(select(null, fun(): Int { return 1 }))
|
||||
}
|
||||
}
|
||||
|
||||
fun <E> select(e: E, f: E): E = TODO()
|
||||
Vendored
+1
-1
@@ -30,7 +30,7 @@ internal class TowerDataElementsForName2() {
|
||||
internal class TowerDataElementsForName3() {
|
||||
val reversedFilteredLocalScopes by <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>lazy<!>(LazyThreadSafetyMode.NONE) {
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>buildList<!> l1@ {
|
||||
buildList l1@ {
|
||||
for (i in lastIndex downTo 0) {
|
||||
val reversedFilteredLocalScopes by lazy(LazyThreadSafetyMode.NONE) {
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ internal class TowerDataElementsForName2() {
|
||||
internal class TowerDataElementsForName3() {
|
||||
val reversedFilteredLocalScopes by <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>lazy<!>(LazyThreadSafetyMode.NONE) {
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>buildList<!> l1@ {
|
||||
buildList l1@ {
|
||||
for (i in lastIndex downTo 0) {
|
||||
val reversedFilteredLocalScopes by lazy(LazyThreadSafetyMode.NONE) {
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
|
||||
Generated
+12
@@ -8937,6 +8937,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/manyIncompleteCandidates.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedPartiallyResolvedCalls.kt")
|
||||
public void testNestedPartiallyResolvedCalls() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/nestedPartiallyResolvedCalls.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedPartiallyResolvedCallsSimple.kt")
|
||||
public void testNestedPartiallyResolvedCallsSimple() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/nestedPartiallyResolvedCallsSimple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("noErrorsForImplicitConstraints.kt")
|
||||
public void testNoErrorsForImplicitConstraints() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user