~ fixes
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt
index 3454d1c..9df071d 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt
@@ -74,9 +74,10 @@
val system: NewConstraintSystemImpl by lazy(LazyThreadSafetyMode.NONE) {
val system = constraintSystemFactory.createConstraintSystem()
- val outerCs = runUnless(baseSystem.usesOuterCs) { inferenceSession.outerCSForCandidate(this) }
- if (outerCs != null) {
- system.addOuterSystem(outerCs)
+ val baseCSFromInferenceSession =
+ runUnless(baseSystem.usesOuterCs) { inferenceSession.baseConstraintStorageForCandidate(this) }
+ if (baseCSFromInferenceSession != null) {
+ system.setBaseSystem(baseCSFromInferenceSession)
system.addOtherSystem(baseSystem)
} else {
system.setBaseSystem(baseSystem)
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession2.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession2.kt
index 6e8a1a1..82f9784 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession2.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession2.kt
@@ -26,9 +26,9 @@
private val inferenceComponents: InferenceComponents,
) : FirInferenceSession() {
- var currentCommonSystem = outerCandidate.system
+ var currentCommonSystem = prepareSharedBaseSystem(outerCandidate.system, inferenceComponents)
+ private set
- private val initialOuterTypeVariables = outerCandidate.system.currentStorage().allTypeVariables.keys
private val qualifiedAccessesToProcess = mutableSetOf<FirExpression>()
override fun <T> shouldAvoidFullCompletion(call: T): Boolean where T : FirResolvable, T : FirStatement {
@@ -89,6 +89,10 @@
(resolutionMode as? ResolutionMode.ContextIndependent.ForDeclaration)?.declaration?.let(outerCandidate.updateDeclarations::add)
}
+ fun applyResultsToMainCandidate() {
+ outerCandidate.system.replaceContentWith(currentCommonSystem.currentStorage())
+ }
+
fun integrateChildSession(
childCalls: Collection<FirStatement>,
childStorage: ConstraintStorage,
@@ -170,7 +174,7 @@
private fun Candidate.isNotTrivial(): Boolean =
usedOuterCs
- override fun outerCSForCandidate(candidate: Candidate): ConstraintStorage? {
+ override fun baseConstraintStorageForCandidate(candidate: Candidate): ConstraintStorage? {
if (candidate.needsToBePostponed()) return currentCommonSystem.currentStorage()
if (candidate.callInfo.arguments.any { it.isLambda() }) return currentCommonSystem.currentStorage()
// TODO: context receivers
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt
index 5e4525c..e38c534 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt
@@ -388,6 +388,8 @@
transformer.context.withOuterConstraintStorage(candidate.system.currentStorage()) {
lambdaArgument.transformSingle(transformer, ResolutionMode.LambdaResolution(expectedReturnTypeRef))
}
+
+ applyResultsToMainCandidate()
}
} else {
transformer.context.inferenceSession.runLambdaCompletion(candidate) {
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession.kt
index 50cc629..19120f9 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession.kt
@@ -42,10 +42,12 @@
private val nonTrivialParentSession: FirInferenceSession? =
resolutionContext.bodyResolveContext.inferenceSession.takeIf { it !== DEFAULT }
+ private val parentConstraintSystem = ((delegateExpression as? FirResolvable)?.candidate()?.system
+ ?: (resolutionContext.bodyResolveContext.inferenceSession as? FirBuilderInferenceSession2)?.currentCommonSystem)
+ ?: components.session.inferenceComponents.createConstraintSystem()
private val currentConstraintSystem =
- (delegateExpression as? FirResolvable)?.candidate()?.system
- ?: (resolutionContext.bodyResolveContext.inferenceSession as? FirBuilderInferenceSession2)?.currentCommonSystem
- ?: components.session.inferenceComponents.createConstraintSystem()
+ prepareSharedBaseSystem(parentConstraintSystem, components.session.inferenceComponents)
+
val currentConstraintStorage: ConstraintStorage get() = currentConstraintSystem.currentStorage()
private val unitType: ConeClassLikeType = components.session.builtinTypes.unitType.type
@@ -100,17 +102,19 @@
private fun <T> T.isProvideDelegate() where T : FirResolvable, T : FirStatement =
isAnyOfDelegateOperators() && (this as FirResolvable).candidate()?.callInfo?.name == OperatorNameConventions.PROVIDE_DELEGATE
- override fun outerCSForCandidate(candidate: Candidate): ConstraintStorage? =
+ override fun baseConstraintStorageForCandidate(candidate: Candidate): ConstraintStorage? =
resolutionContext.bodyResolveContext.outerConstraintStorage.takeIf { it !== ConstraintStorage.Empty }
fun completeSessionOrPostponeIfNonRoot(afterCompletion: (ConeSubstitutor) -> Unit) {
check(!wasCompletionRun)
wasCompletionRun = true
+ parentConstraintSystem.addOtherSystem(currentConstraintStorage)
+
(nonTrivialParentSession as? FirBuilderInferenceSession2)?.apply {
integrateChildSession(
partiallyResolvedCalls.map { it.first as FirStatement },
- currentConstraintStorage,
+ parentConstraintSystem.currentStorage(),
afterCompletion,
)
return
@@ -118,7 +122,7 @@
val completedCalls = completeCandidatesForRootSession()
- val finalSubstitutor = currentConstraintSystem.asReadOnlyStorage()
+ val finalSubstitutor = parentConstraintSystem.asReadOnlyStorage()
.buildAbstractResultingSubstitutor(components.session.typeContext) as ConeSubstitutor
val callCompletionResultsWriter = callCompleter.createCompletionResultsWriter(
@@ -134,7 +138,7 @@
}
private fun completeCandidatesForRootSession(): List<FirResolvable> {
- val commonSystem = currentConstraintSystem.apply { prepareForGlobalCompletion() }
+ val parentSystem = parentConstraintSystem.apply { prepareForGlobalCompletion() }
val notCompletedCalls =
buildList {
@@ -149,7 +153,7 @@
resolutionContext.bodyResolveContext.withInferenceSession(DEFAULT) {
@Suppress("UNCHECKED_CAST")
components.callCompleter.completer.complete(
- commonSystem.asConstraintSystemCompleterContext(),
+ parentSystem.asConstraintSystemCompleterContext(),
ConstraintSystemCompletionMode.FULL,
notCompletedCalls as List<FirStatement>,
unitType, resolutionContext
@@ -165,7 +169,7 @@
found
}.candidate
callCompleter.createPostponedArgumentsAnalyzer(resolutionContext).analyze(
- commonSystem,
+ parentSystem,
lambdaAtom,
containingCandidateForLambda,
)
@@ -173,7 +177,7 @@
}
for (candidate in notCompletedCalls.mapNotNull { it.candidate() }) {
- for (error in commonSystem.errors) {
+ for (error in parentSystem.errors) {
candidate.addDiagnostic(InferenceError(error))
}
}
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirInferenceSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirInferenceSession.kt
index 48189a3..5366b82 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirInferenceSession.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirInferenceSession.kt
@@ -13,6 +13,7 @@
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionMode
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
+import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
abstract class FirInferenceSession {
companion object {
@@ -31,6 +32,16 @@
// Do nothing
}
}
+
+ @JvmStatic
+ protected fun prepareSharedBaseSystem(
+ outerSystem: NewConstraintSystemImpl,
+ components: InferenceComponents,
+ ): NewConstraintSystemImpl {
+ return components.createConstraintSystem().apply {
+ addOuterSystem(outerSystem.currentStorage())
+ }
+ }
}
open fun <T> runLambdaCompletion(candidate: Candidate, block: () -> T): T = block()
@@ -54,5 +65,5 @@
open fun <R> onCandidatesResolution(call: FirFunctionCall, candidatesResolutionCallback: () -> R) = candidatesResolutionCallback()
- open fun outerCSForCandidate(candidate: Candidate): ConstraintStorage? = null
+ open fun baseConstraintStorageForCandidate(candidate: Candidate): ConstraintStorage? = null
}
diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt
index 0837d85..7bdff81 100644
--- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt
+++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt
@@ -338,6 +338,8 @@
}
private fun addOtherSystem(otherSystem: ConstraintStorage, isAddingOuter: Boolean, clearNotFixedTypeVariables: Boolean = false) {
+ runOuterCSRelatedAssertions(otherSystem, isAddingOuter)
+
if (otherSystem.allTypeVariables.isNotEmpty()) {
otherSystem.allTypeVariables.forEach {
transactionRegisterVariable(it.value)
@@ -369,7 +371,6 @@
storage.postponedTypeVariables.addAll(otherSystem.postponedTypeVariables)
storage.constraintsFromAllForkPoints.addAll(otherSystem.constraintsFromAllForkPoints)
- runOuterCSRelatedAssertions(otherSystem, isAddingOuter)
}
@@ -383,9 +384,9 @@
require(storage.usesOuterCs)
if (!isAddingOuter) {
-// require(storage.outerSystemVariablesPrefixSize == otherSystem.outerSystemVariablesPrefixSize) {
-// "Expected to be ${otherSystem.outerSystemVariablesPrefixSize}, but ${storage.outerSystemVariablesPrefixSize} found"
-// }
+ require(storage.outerSystemVariablesPrefixSize == otherSystem.outerSystemVariablesPrefixSize) {
+ "Expected to be ${otherSystem.outerSystemVariablesPrefixSize}, but ${storage.outerSystemVariablesPrefixSize} found"
+ }
}
}
diff --git a/compiler/testData/diagnostics/tests/builderInference/issues/kt63841.fir.kt b/compiler/testData/diagnostics/tests/builderInference/issues/kt63841.fir.kt
index 063db80..90a3e34 100644
--- a/compiler/testData/diagnostics/tests/builderInference/issues/kt63841.fir.kt
+++ b/compiler/testData/diagnostics/tests/builderInference/issues/kt63841.fir.kt
@@ -28,7 +28,7 @@
variable = TargetType()
<!BUILDER_INFERENCE_STUB_RECEIVER!>variable<!>.targetTypeMemberFunction()
variable = <!ASSIGNMENT_TYPE_MISMATCH!>DifferentType()<!>
- <!BUILDER_INFERENCE_STUB_RECEIVER!>variable<!>.targetTypeMemberFunction()
+ variable.<!UNRESOLVED_REFERENCE!>targetTypeMemberFunction<!>()
variable = TargetType()
<!BUILDER_INFERENCE_STUB_RECEIVER!>variable<!>.targetTypeMemberFunction()
}
diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/nestedLambdasWithOverloadResolutionByReturnType.kt b/compiler/testData/diagnostics/tests/inference/builderInference/nestedLambdasWithOverloadResolutionByReturnType.kt
new file mode 100644
index 0000000..22e090e
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/inference/builderInference/nestedLambdasWithOverloadResolutionByReturnType.kt
@@ -0,0 +1,27 @@
+// FIR_IDENTICAL
+// WITH_STDLIB
+
+class Controller<T> {
+ fun yield(t: T): Boolean = true
+}
+
+fun <S> generate(g: suspend Controller<S>.() -> Unit): S = TODO()
+
+fun foo(x1: List<String>, x2: List<String>) {
+ generate {
+ yield(
+ x1.flatMap1 {
+ x2.map2 { "" }
+ }
+ )
+ }.length
+}
+
+fun <T1> Iterable<T1>.flatMap1(transform: (T1) -> String): String = TODO()
+
+@OptIn(kotlin.experimental.ExperimentalTypeInference::class)
+@OverloadResolutionByLambdaReturnType
+@kotlin.jvm.JvmName("flatMapSequence")
+fun <T2> Iterable<T2>.flatMap1(transform: (T2) -> Int): Int = TODO()
+
+fun <T3, R3> T3.map2(transform: (T3) -> R3): R3 = TODO()
\ No newline at end of file
diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/memberScope.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/memberScope.fir.kt
index ddcd09e..e3751ff 100644
--- a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/memberScope.fir.kt
+++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/memberScope.fir.kt
@@ -39,7 +39,7 @@
val x = get()
<!BUILDER_INFERENCE_STUB_RECEIVER!>x<!>?.hashCode()
x?.<!NONE_APPLICABLE!>equals<!>(1)
- x<!UNSAFE_CALL!>.<!>equals("")
+ x.<!NONE_APPLICABLE!>equals<!>("")
}
val ret3 = build {
emit(1)
@@ -59,12 +59,12 @@
if (x != null) {
<!BUILDER_INFERENCE_STUB_RECEIVER!>x<!><!UNNECESSARY_SAFE_CALL!>?.<!>hashCode()
x<!UNNECESSARY_SAFE_CALL!>?.<!><!NONE_APPLICABLE!>equals<!>(1)
- x.<!UNRESOLVED_REFERENCE!>equals<!>("")
- x.hashCode()
- x.toString()
- x.test()
+ x.<!NONE_APPLICABLE!>equals<!>("")
+ <!BUILDER_INFERENCE_STUB_RECEIVER!>x<!>.hashCode()
+ <!BUILDER_INFERENCE_STUB_RECEIVER!>x<!>.toString()
+ <!BUILDER_INFERENCE_STUB_RECEIVER!>x<!>.test()
<!BUILDER_INFERENCE_STUB_RECEIVER!>x<!><!UNNECESSARY_SAFE_CALL!>?.<!>test2()
- x.test2()
+ <!BUILDER_INFERENCE_STUB_RECEIVER!>x<!>.test2()
}
""
diff --git a/compiler/testData/diagnostics/tests/resolve/varInsideLambdaThatPassedToExtensionFunctionWithTypeParametersThatDefinedInsideThisLambda.fir.kt b/compiler/testData/diagnostics/tests/resolve/varInsideLambdaThatPassedToExtensionFunctionWithTypeParametersThatDefinedInsideThisLambda.fir.kt
index db81fc4..61acbba 100644
--- a/compiler/testData/diagnostics/tests/resolve/varInsideLambdaThatPassedToExtensionFunctionWithTypeParametersThatDefinedInsideThisLambda.fir.kt
+++ b/compiler/testData/diagnostics/tests/resolve/varInsideLambdaThatPassedToExtensionFunctionWithTypeParametersThatDefinedInsideThisLambda.fir.kt
@@ -12,6 +12,6 @@
"Error: $x"
x.<!UNRESOLVED_REFERENCE!>length<!>
}
- x<!UNSAFE_CALL!>.<!>length
+ x.<!UNRESOLVED_REFERENCE!>length<!>
}
}