Skip to content

Commit 555d8ee

Browse files
committed
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
1 parent 8b81c37 commit 555d8ee

File tree

12 files changed

+122
-7
lines changed

12 files changed

+122
-7
lines changed

analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt

+5-1
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,13 @@ class FirCallCompleter(
111111

112112
ConstraintSystemCompletionMode.PARTIAL -> {
113113
runCompletionForCall(candidate, completionMode, call, initialType, analyzer)
114-
if (inferenceSession !is FirBuilderInferenceSession) {
114+
115+
// Add top-level delegate call as partially resolved to inference session
116+
if (resolutionMode is ResolutionMode.ContextDependentDelegate) {
117+
require(inferenceSession is FirDelegatedPropertyInferenceSession)
115118
inferenceSession.addPartiallyResolvedCall(call)
116119
}
120+
117121
CompletionResult(call, false)
118122
}
119123

compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,9 @@ open class FirDeclarationsResolveTransformer(
318318
wrappedDelegateExpression: FirWrappedDelegateExpression,
319319
data: ResolutionMode,
320320
): FirStatement {
321-
// First, resolve delegate expression in dependent context
322-
val delegateExpression = wrappedDelegateExpression.expression.transformSingle(transformer, ResolutionMode.ContextDependent)
321+
// First, resolve delegate expression in dependent context, and add potentially partially resolved call to inference session
322+
// (that is why we use ContextDependentDelegate instead of plain ContextDependent)
323+
val delegateExpression = wrappedDelegateExpression.expression.transformSingle(transformer, ResolutionMode.ContextDependentDelegate)
323324
.transformSingle(components.integerLiteralAndOperatorApproximationTransformer, null)
324325

325326
// Second, replace result type of delegate expression with stub type if delegate not yet resolved

compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.fir.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ class A(outer: Outer) {
99
var g: String by outer.getContainer().getMyProperty()
1010

1111

12-
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<!>())
13-
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<!>())
12+
var b: String by <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>(getMyProperty())
13+
var r: String by <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>(outer.getContainer().getMyProperty())
1414
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())
1515
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
1616
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// FIR_IDENTICAL
2+
// WITH_STDLIB
3+
// ISSUE: KT-57543
4+
5+
// FILE: JavaClass.java
6+
import kotlin.jvm.functions.Function0;
7+
8+
public class JavaClass {
9+
10+
public static class Val<T> {
11+
private final Function0<T> initializer;
12+
public Val(Function0<T> initializer) {
13+
this.initializer = initializer;
14+
}
15+
public final T getValue(Object instance, Object metadata) {
16+
return initializer.invoke();
17+
}
18+
}
19+
20+
public static <T> Val<T> lazySoft(Function0<T> initializer) {
21+
return new Val<T>(initializer);
22+
}
23+
}
24+
25+
// FILE: main.kt
26+
27+
class A(
28+
val c: Int? = 0,
29+
myType: (() -> Int)? = null
30+
) {
31+
val arguments: A by JavaClass.lazySoft {
32+
A(myType = if (false) null else fun(): Int { return c!! })
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// FIR_IDENTICAL
2+
// ISSUE: KT-57543
3+
4+
class KotlinVal<T>(initializer: () -> T) {
5+
operator fun getValue(instance: Any?, metadata: Any?): T = TODO()
6+
}
7+
8+
class A(
9+
myType: (() -> Int)?
10+
) {
11+
val arguments: A by KotlinVal {
12+
A(select(null, fun(): Int { return 1 }))
13+
}
14+
}
15+
16+
fun <E> select(e: E, f: E): E = TODO()

compiler/testData/diagnostics/testsWithStdLib/builderInference/buildListToUpperBoundInLazy.fir.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ internal class TowerDataElementsForName2() {
3030
internal class TowerDataElementsForName3() {
3131
val reversedFilteredLocalScopes by <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>lazy<!>(LazyThreadSafetyMode.NONE) {
3232
@OptIn(ExperimentalStdlibApi::class)
33-
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>buildList<!> l1@ {
33+
buildList l1@ {
3434
for (i in lastIndex downTo 0) {
3535
val reversedFilteredLocalScopes by lazy(LazyThreadSafetyMode.NONE) {
3636
@OptIn(ExperimentalStdlibApi::class)

compiler/testData/diagnostics/testsWithStdLib/builderInference/buildListToUpperBoundInLazyForbidden.fir.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ internal class TowerDataElementsForName2() {
3030
internal class TowerDataElementsForName3() {
3131
val reversedFilteredLocalScopes by <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>lazy<!>(LazyThreadSafetyMode.NONE) {
3232
@OptIn(ExperimentalStdlibApi::class)
33-
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>buildList<!> l1@ {
33+
buildList l1@ {
3434
for (i in lastIndex downTo 0) {
3535
val reversedFilteredLocalScopes by lazy(LazyThreadSafetyMode.NONE) {
3636
@OptIn(ExperimentalStdlibApi::class)

compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)