From ad30c6c3802fc39fa9fefef766546802c7111d73 Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Wed, 13 Jan 2021 21:28:23 +0300 Subject: [PATCH] FIR: Fix callable references resolution when they're being returned from lambdas --- .../jetbrains/kotlin/fir/FirCallResolver.kt | 6 ++- .../inference/ConstraintSystemCompleter.kt | 3 +- .../inference/PostponedArgumentsAnalyzer.kt | 2 +- .../fir/resolve/inference/PostponedAtoms.kt | 17 +++++--- .../boxInline/callableReference/kt15449.kt | 3 +- .../callableReference/lambdaResult.fir.kt | 43 ------------------- .../tests/callableReference/lambdaResult.kt | 1 + 7 files changed, 19 insertions(+), 56 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/callableReference/lambdaResult.fir.kt diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index 655c3f8994e..a4f740ade2f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -263,13 +263,15 @@ class FirCallResolver( conflictResolver.chooseMaximallySpecificCandidates(bestCandidates, discriminateGenerics = false) } + resolvedCallableReferenceAtom.hasBeenResolvedOnce = true + when { noSuccessfulCandidates -> { return false } reducedCandidates.size > 1 -> { - if (resolvedCallableReferenceAtom.postponed) return false - resolvedCallableReferenceAtom.postponed = true + if (resolvedCallableReferenceAtom.hasBeenPostponed) return false + resolvedCallableReferenceAtom.hasBeenPostponed = true return true } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt index 3a5f00f7cdf..4a0d282d8de 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt @@ -291,8 +291,9 @@ class ConstraintSystemCompleter(private val components: BodyResolveComponents) { postponedAtom.collectNotFixedVariables() } postponedAtom is ResolvedCallableReferenceAtom -> { - if (postponedAtom.postponed) + if (postponedAtom.mightNeedAdditionalResolution) { postponedAtom.collectNotFixedVariables() + } } } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt index 56c5d4aa1bc..ec55504908f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt @@ -68,7 +68,7 @@ class PostponedArgumentsAnalyzer( } private fun processCallableReference(atom: ResolvedCallableReferenceAtom, candidate: Candidate) { - if (atom.postponed) { + if (atom.mightNeedAdditionalResolution) { callResolver.resolveCallableReference(candidate.csBuilder, atom) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedAtoms.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedAtoms.kt index c7f1ab6bfc8..823544c872e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedAtoms.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedAtoms.kt @@ -116,35 +116,38 @@ class ResolvedCallableReferenceAtom( val lhs: DoubleColonLHS?, private val session: FirSession ) : PostponedResolvedAtom(), PostponedCallableReferenceMarker { - // TODO: in several places atoms are filtered by the marker interface - potential overhead/errors - var postponed: Boolean = false + + var hasBeenResolvedOnce: Boolean = false + var hasBeenPostponed: Boolean = false + + val mightNeedAdditionalResolution get() = !hasBeenResolvedOnce || hasBeenPostponed var resultingCandidate: Pair? = null override val inputTypes: Collection get() { - if (!postponed) return emptyList() + if (!hasBeenPostponed) return emptyList() return extractInputOutputTypesFromCallableReferenceExpectedType(expectedType, session)?.inputTypes ?: listOfNotNull(expectedType) } override val outputType: ConeKotlinType? get() { - if (!postponed) return null + if (!hasBeenPostponed) return null return extractInputOutputTypesFromCallableReferenceExpectedType(expectedType, session)?.outputType } override val expectedType: ConeKotlinType? - get() = if (!postponed) + get() = if (!hasBeenPostponed) initialExpectedType else revisedExpectedType ?: initialExpectedType override var revisedExpectedType: ConeKotlinType? = null - get() = if (postponed) field else expectedType + get() = if (hasBeenPostponed) field else expectedType private set override fun reviseExpectedType(expectedType: KotlinTypeMarker) { - if (!postponed) return + if (!mightNeedAdditionalResolution) return require(expectedType is ConeKotlinType) revisedExpectedType = expectedType } diff --git a/compiler/testData/codegen/boxInline/callableReference/kt15449.kt b/compiler/testData/codegen/boxInline/callableReference/kt15449.kt index eb591ffe6b8..265fe026478 100644 --- a/compiler/testData/codegen/boxInline/callableReference/kt15449.kt +++ b/compiler/testData/codegen/boxInline/callableReference/kt15449.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // FILE: 1.kt package test @@ -38,4 +37,4 @@ class A { fun box(): String { A().test() return result -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/callableReference/lambdaResult.fir.kt b/compiler/testData/diagnostics/tests/callableReference/lambdaResult.fir.kt deleted file mode 100644 index 00b7794fa25..00000000000 --- a/compiler/testData/diagnostics/tests/callableReference/lambdaResult.fir.kt +++ /dev/null @@ -1,43 +0,0 @@ -// SKIP_TXT -// !DIAGNOSTICS: -UNUSED_PARAMETER -// !LANGUAGE: +NewInference - -interface Inv - -fun Inv.foo( - handler: () -> ((command: E) -> Unit) -) {} - -fun bar(x: Int) {} -fun bar(x: String) {} - -fun bar1(arg: Int) {} -fun foo1(f: () -> (Int) -> Unit) = "" - -fun main(x: Inv) { - x.foo { - if (x.hashCode() == 0) return@foo ::bar - - ::bar - } - - x.foo { - if (x.hashCode() == 0) return@foo ::bar - - ::bar - } - - foo1 { - ::bar1 - } - - foo1 { - return@foo1 ::bar1 - } - - foo1 { - if (x.hashCode() == 0) return@foo1 ::bar - - ::bar - } -} diff --git a/compiler/testData/diagnostics/tests/callableReference/lambdaResult.kt b/compiler/testData/diagnostics/tests/callableReference/lambdaResult.kt index 1391ebe2b86..4b9b62cc8e4 100644 --- a/compiler/testData/diagnostics/tests/callableReference/lambdaResult.kt +++ b/compiler/testData/diagnostics/tests/callableReference/lambdaResult.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // SKIP_TXT // !DIAGNOSTICS: -UNUSED_PARAMETER // !LANGUAGE: +NewInference