~ initial
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 efb221c..3454d1c 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
@@ -28,6 +28,7 @@
 import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
 import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
 import org.jetbrains.kotlin.util.CodeFragmentAdjustment
+import org.jetbrains.kotlin.utils.addToStdlib.runUnless
 
 class Candidate(
     symbol: FirBasedSymbol<*>,
@@ -73,8 +74,8 @@
     val system: NewConstraintSystemImpl by lazy(LazyThreadSafetyMode.NONE) {
         val system = constraintSystemFactory.createConstraintSystem()
 
-        val outerCs = inferenceSession.outerCSForCandidate(this)
-        if (outerCs != null && !baseSystem.usesOuterCs) {
+        val outerCs = runUnless(baseSystem.usesOuterCs) { inferenceSession.outerCSForCandidate(this) }
+        if (outerCs != null) {
             system.addOuterSystem(outerCs)
             system.addOtherSystem(baseSystem)
         } else {
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt
index 71880e3..badbb94 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt
@@ -36,18 +36,20 @@
         private fun buildBaseSystem(context: ResolutionContext, callInfo: CallInfo): ConstraintStorage {
             val system = context.inferenceComponents.createConstraintSystem()
 
-            val subsystems = buildList {
+            val argumentSubsystems = buildList {
                 callInfo.arguments.forEach {
                     processAllSubsystemsFromExpression(it, this::add)
                 }
             }
 
-            val lastSubsystemWithOuterCs = subsystems.lastOrNull { it.usesOuterCs }
+            // If any of the arguments uses outer CS, then all of them effectively share it, so we might add the last one as
+            // containing the most up-to-date version.
+            val lastSubsystemWithOuterCs = argumentSubsystems.lastOrNull { it.usesOuterCs }
             if (lastSubsystemWithOuterCs != null) {
                 system.setBaseSystem(lastSubsystemWithOuterCs)
             }
 
-            subsystems.forEach {
+            argumentSubsystems.forEach {
                 if (!it.usesOuterCs) {
                     system.addOtherSystem(it)
                 }
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 8944560..2a59d86 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
@@ -48,15 +48,7 @@
         context: ResolutionContext,
         collectVariablesFromContext: Boolean = false,
         analyze: (PostponedResolvedAtom) -> Unit,
-    ) = with(c) {
-//        outerTypeVariables?.let {
-//            return@with withTypeVariablesThatAreCountedAsProperTypes(it) {
-//                runCompletion(completionMode, topLevelAtoms, candidateReturnType, context, collectVariablesFromContext, analyze)
-//            }
-//        }
-
-        runCompletion(completionMode, topLevelAtoms, candidateReturnType, context, collectVariablesFromContext, analyze)
-    }
+    ) = c.runCompletion(completionMode, topLevelAtoms, candidateReturnType, context, collectVariablesFromContext, analyze)
 
     private fun ConstraintSystemCompletionContext.runCompletion(
         completionMode: ConstraintSystemCompletionMode,
@@ -82,16 +74,6 @@
                 )
             ) return
 
-            if (completionMode == ConstraintSystemCompletionMode.ONLY_LAMBDAS) {
-                if (analyzeNextReadyPostponedArgument(languageVersionSettings, postponedArguments, completionMode, analyze))
-                    continue
-
-                if (tryToCompleteWithBuilderInference(completionMode, postponedArguments, analyze))
-                    continue
-
-                break
-            }
-
             // Stage 1: analyze postponed arguments with fixed parameter types
             if (analyzeArgumentWithFixedParameterTypes(languageVersionSettings, postponedArguments, analyze))
                 continue
@@ -113,7 +95,6 @@
                     // NB: FE 1.0 does not perform this check
                     it.revisedExpectedType == null
                 }
-
             val dependencyProvider =
                 TypeVariableDependencyInformationProvider(notFixedTypeVariables, postponedArguments, topLevelType, this)
 
@@ -129,7 +110,7 @@
             if (wasBuiltNewExpectedTypeForSomeArgument)
                 continue
 
-            if (completionMode == ConstraintSystemCompletionMode.FULL || completionMode == ConstraintSystemCompletionMode.PARTIAL_BI) {
+            if (completionMode == ConstraintSystemCompletionMode.FULL || completionMode == ConstraintSystemCompletionMode.PARTIAL_PCLA) {
                 // Stage 3: fix variables for parameter types of all postponed arguments
                 for (argument in postponedArguments) {
                     val variableWasFixed = postponedArgumentsInputTypesResolver.fixNextReadyVariableForParameterTypeIfNeeded(
@@ -169,13 +150,13 @@
 
             // Stage 7: try to complete call with the builder inference if there are uninferred type variables
             val areThereAppearedProperConstraintsForSomeVariable = tryToCompleteWithBuilderInference(
-                completionMode, postponedArguments, analyze
+                completionMode, topLevelType, postponedArguments, collectVariablesFromContext, topLevelAtoms, analyze,
             )
 
             if (areThereAppearedProperConstraintsForSomeVariable)
                 continue
 
-            if (completionMode == ConstraintSystemCompletionMode.PARTIAL_BI) {
+            if (completionMode == ConstraintSystemCompletionMode.PARTIAL_PCLA) {
                 // Complete all lambdas, maybe with semi-fixing type variables used as top-level input types
                 if (analyzeRemainingNotAnalyzedPostponedArgument(postponedArguments, analyze))
                     continue
@@ -186,27 +167,14 @@
                 completionMode, topLevelAtoms, topLevelType, postponedArguments
             )
 
-            if (completionMode == ConstraintSystemCompletionMode.PARTIAL_BI) {
-                for (argument in postponedArguments) {
-                    val variableForFixation = postponedArgumentsInputTypesResolver.findNextReadyVariableForParameterTypeIfNeeded(
-                        this,
-                        argument,
-                        postponedArguments,
-                        topLevelType,
-                        dependencyProvider,
-                    ) ?: continue
-
-                    assert(!variableForFixation.hasProperConstraint) {
-                        "At this stage there should be no remaining variables with proper constraints from input types"
-                    }
-
-                    val variableWithConstraints = notFixedTypeVariables.getValue(variableForFixation.variable)
-                    processVariableWhenNotEnoughInformation(variableWithConstraints, topLevelAtoms)
-                }
+            if (completionMode == ConstraintSystemCompletionMode.PARTIAL_PCLA) {
+                reportNotEnoughInformationForTypeVariablesRequiredForInputTypesOfLambdas(
+                    postponedArguments, topLevelType, dependencyProvider, topLevelAtoms
+                )
             }
 
             // Stage 9: force analysis of remaining not analyzed postponed arguments and rerun stages if there are
-            if (completionMode == ConstraintSystemCompletionMode.FULL || completionMode == ConstraintSystemCompletionMode.PARTIAL_BI) {
+            if (completionMode == ConstraintSystemCompletionMode.FULL || completionMode == ConstraintSystemCompletionMode.PARTIAL_PCLA) {
                 if (analyzeRemainingNotAnalyzedPostponedArgument(postponedArguments, analyze))
                     continue
             }
@@ -215,6 +183,30 @@
         }
     }
 
+    private fun ConstraintSystemCompletionContext.reportNotEnoughInformationForTypeVariablesRequiredForInputTypesOfLambdas(
+        postponedArguments: List<PostponedResolvedAtom>,
+        topLevelType: ConeKotlinType,
+        dependencyProvider: TypeVariableDependencyInformationProvider,
+        topLevelAtoms: List<FirStatement>,
+    ) {
+        for (argument in postponedArguments) {
+            val variableForFixation = postponedArgumentsInputTypesResolver.findNextReadyVariableForParameterTypeIfNeeded(
+                this,
+                argument,
+                postponedArguments,
+                topLevelType,
+                dependencyProvider,
+            ) ?: continue
+
+            assert(!variableForFixation.hasProperConstraint) {
+                "At this stage there should be no remaining variables with proper constraints from input types"
+            }
+
+            val variableWithConstraints = notFixedTypeVariables.getValue(variableForFixation.variable)
+            processVariableWhenNotEnoughInformation(variableWithConstraints, topLevelAtoms)
+        }
+    }
+
     private fun ConstraintSystemCompletionContext.findFirstVariableForFixation(
         collectVariablesFromContext: Boolean,
         topLevelAtoms: List<FirStatement>,
@@ -222,14 +214,12 @@
         completionMode: ConstraintSystemCompletionMode,
         topLevelType: ConeKotlinType,
     ): VariableFixationFinder.VariableForFixation? {
-        val allTypeVariables = getOrderedAllTypeVariables(
-            collectVariablesFromContext,
-            topLevelAtoms
-        )
-
         return variableFixationFinder.findFirstVariableForFixation(
             this,
-            allTypeVariables,
+            getOrderedAllTypeVariables(
+                collectVariablesFromContext,
+                topLevelAtoms
+            ),
             postponedArguments,
             completionMode,
             topLevelType
@@ -244,15 +234,13 @@
      */
     private fun ConstraintSystemCompletionContext.tryToCompleteWithBuilderInference(
         completionMode: ConstraintSystemCompletionMode,
+        topLevelType: ConeKotlinType,
         postponedArguments: List<PostponedResolvedAtom>,
+        collectVariablesFromContext: Boolean,
+        topLevelAtoms: List<FirStatement>,
         analyze: (PostponedResolvedAtom) -> Unit,
     ): Boolean {
-        val modes = setOf(
-            ConstraintSystemCompletionMode.FULL,
-            ConstraintSystemCompletionMode.ONLY_LAMBDAS,
-            ConstraintSystemCompletionMode.PARTIAL_BI
-        )
-        if (completionMode !in modes) return false
+        if (completionMode != ConstraintSystemCompletionMode.FULL && completionMode != ConstraintSystemCompletionMode.PARTIAL_PCLA) return false
 
         // If we use the builder inference anyway (if the annotation is presented), then we are already analysed builder inference lambdas
         if (!languageVersionSettings.supportsFeature(LanguageFeature.UseBuilderInferenceOnlyIfNeeded)) return false
@@ -272,7 +260,18 @@
             anyAnalyzed = true
         }
 
-        return anyAnalyzed
+        // For PCLA, we don't expect new TVs are fixed since they might be related to outer CS.
+        // But we really require all the lambdas should be analyzed fully for each PCLA-postponed top-level call.
+        if (anyAnalyzed && completionMode == ConstraintSystemCompletionMode.PARTIAL_PCLA) return true
+
+        val variableForFixation = variableFixationFinder.findFirstVariableForFixation(
+            this, getOrderedAllTypeVariables(collectVariablesFromContext, topLevelAtoms), postponedArguments, completionMode, topLevelType
+        )
+
+        // continue completion (rerun stages) only if ready for fixation variables with proper constraints have appeared
+        // (after analysing a lambda with the builder inference)
+        // otherwise we don't continue and report "not enough type information" error
+        return variableForFixation?.hasProperConstraint == true
     }
 
     private fun transformToAtomWithNewFunctionExpectedType(
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 cfd0377..5e4525c 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
@@ -94,7 +94,7 @@
 
             when {
                 inferenceSession is FirBuilderInferenceSession2 -> when {
-                    inferenceSession.shouldAvoidFullCompletion(call) && it == ConstraintSystemCompletionMode.FULL -> ConstraintSystemCompletionMode.PARTIAL_BI
+                    inferenceSession.shouldAvoidFullCompletion(call) && it == ConstraintSystemCompletionMode.FULL -> ConstraintSystemCompletionMode.PARTIAL_PCLA
                     else -> it
                 }
                 else -> when {
@@ -135,7 +135,7 @@
                 }
             }
 
-            ConstraintSystemCompletionMode.PARTIAL, ConstraintSystemCompletionMode.PARTIAL_BI, ConstraintSystemCompletionMode.ONLY_LAMBDAS -> {
+            ConstraintSystemCompletionMode.PARTIAL, ConstraintSystemCompletionMode.PARTIAL_PCLA -> {
                 runCompletionForCall(candidate, completionMode, call, initialType, analyzer)
 
                 if (inferenceSession is FirDelegatedPropertyInferenceSession || inferenceSession is FirBuilderInferenceSession2) {
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt
index 3032211..e9e9fac 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt
@@ -482,11 +482,6 @@
 
         val candidateSystem = candidate.system
         val candidateStorage = candidateSystem.currentStorage()
-        val allTypeVariables = candidateStorage.allTypeVariables.keys.toList()
-        // Subset of type variables obtained from the `provideDelegate` call
-        val typeVariablesRelatedToProvideDelegate =
-            allTypeVariables.subList(candidateStorage.outerSystemVariablesPrefixSize, allTypeVariables.size).toSet()
-
         val variableWithConstraints =
             candidateSystem.notFixedTypeVariables[typeVariable] ?: error("Not found type variable $typeVariable")
 
@@ -495,7 +490,7 @@
         // Temporary declare all the "outer" variables as proper (i.e., all inner variables as improper)
         // Without that, all variables (both inner and outer ones) would be considered as improper,
         // while we want to fix to assume `Delegate<Tv>` as proper because `Tv` belongs to the outer system
-        candidateSystem.withTypeVariablesThatAreNotCountedAsProperTypes(typeVariablesRelatedToProvideDelegate) {
+        candidateSystem.withTypeVariablesThatAreCountedAsProperTypes(candidateSystem.outerTypeVariables.orEmpty()) {
             // TODO: reconsider the approach here (KT-61781 for tracking)
             // Actually, this code might fail with an exception in some rare cases (see KT-61781)
             // The problem is that in the issue example, when fixing T type variable, it has two upper bounds: X and Delegate<Y>
@@ -507,7 +502,7 @@
             // it seems like they do something relevant.
             resultType = inferenceComponents.resultTypeResolver.findResultTypeOrNull(
                 candidateSystem, variableWithConstraints, TypeVariableDirectionCalculator.ResolveDirection.UNKNOWN
-            ) as? ConeKotlinType ?: return@withTypeVariablesThatAreNotCountedAsProperTypes
+            ) as? ConeKotlinType ?: return@withTypeVariablesThatAreCountedAsProperTypes
 
 
             check(!candidateStorage.hasContradiction) { "We only should try fixing variables on successful provideDelegate candidate" }
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt
index 95db3a3..333ba61 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt
@@ -15,10 +15,7 @@
 import org.jetbrains.kotlin.fir.declarations.utils.isLocal
 import org.jetbrains.kotlin.fir.diagnostics.*
 import org.jetbrains.kotlin.fir.expressions.*
-import org.jetbrains.kotlin.fir.expressions.FirOperation.AS
-import org.jetbrains.kotlin.fir.expressions.FirOperation.IS
-import org.jetbrains.kotlin.fir.expressions.FirOperation.NOT_IS
-import org.jetbrains.kotlin.fir.expressions.FirOperation.SAFE_AS
+import org.jetbrains.kotlin.fir.expressions.FirOperation.*
 import org.jetbrains.kotlin.fir.expressions.builder.*
 import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedArgumentList
 import org.jetbrains.kotlin.fir.expressions.impl.toAnnotationArgumentMapping
@@ -236,8 +233,8 @@
         data: ResolutionMode,
     ): FirStatement {
         return callResolver.resolveVariableAccessAndSelectCandidate(
-            qualifiedAccessExpression, isUsedAsReceiver, isUsedAsGetClassReceiver, callSite
-        , data)
+            qualifiedAccessExpression, isUsedAsReceiver, isUsedAsGetClassReceiver, callSite, data
+        )
     }
 
     fun transformSuperReceiver(
diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzerContext.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzerContext.kt
index fa1f1e6..d54f073 100644
--- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzerContext.kt
+++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzerContext.kt
@@ -11,7 +11,7 @@
 import org.jetbrains.kotlin.types.model.*
 
 interface PostponedArgumentsAnalyzerContext : TypeSystemInferenceExtensionContext {
-    abstract val notFixedTypeVariables: Map<TypeConstructorMarker, VariableWithConstraints>
+    val notFixedTypeVariables: Map<TypeConstructorMarker, VariableWithConstraints>
 
     fun buildCurrentSubstitutor(additionalBindings: Map<TypeConstructorMarker, KotlinTypeMarker>): TypeSubstitutorMarker
     fun buildNotFixedVariablesToStubTypesSubstitutor(): TypeSubstitutorMarker
diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintSystemCompletionContext.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintSystemCompletionContext.kt
index 5fccb97..2f5e92d 100644
--- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintSystemCompletionContext.kt
+++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintSystemCompletionContext.kt
@@ -20,8 +20,6 @@
     abstract override val fixedTypeVariables: Map<TypeConstructorMarker, KotlinTypeMarker>
     abstract override val postponedTypeVariables: List<TypeVariableMarker>
 
-
-
     abstract fun getBuilder(): ConstraintSystemBuilder
 
     // type can be proper if it not contains not fixed type variables
@@ -121,6 +119,5 @@
      * @see [org.jetbrains.kotlin.resolve.calls.inference.components.VariableFixationFinder.Context.typeVariablesThatAreNotCountedAsProperTypes]
      * @see [org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclarationsResolveTransformer.fixInnerVariablesForProvideDelegateIfNeeded]
      */
-    abstract fun <R> withTypeVariablesThatAreNotCountedAsProperTypes(typeVariables: Set<TypeConstructorMarker>, block: () -> R): R
     abstract fun <R> withTypeVariablesThatAreCountedAsProperTypes(typeVariables: Set<TypeConstructorMarker>, block: () -> R): R
 }
diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintSystemCompletionMode.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintSystemCompletionMode.kt
index 474d3cc..899b85e 100644
--- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintSystemCompletionMode.kt
+++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintSystemCompletionMode.kt
@@ -19,7 +19,6 @@
      * ```
      */
     PARTIAL,
-    PARTIAL_BI,
-    ONLY_LAMBDAS,
+    PARTIAL_PCLA,
     UNTIL_FIRST_LAMBDA
 }
diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt
index aec9f52..10c3ca1 100644
--- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt
+++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt
@@ -42,15 +42,13 @@
                 }
 
         /**
-         * If not null, that property means that we should assume temporary
-         * `allTypeVariables.keys.minus(typeVariablesThatAreNotCountedAsProperTypes)` as proper types when fixating some variables.
+         * If not null, that property means that we should assume temporary them all as proper types when fixating some variables.
          *
          * By default, if that property is null, we assume all `allTypeVariables` as not proper.
          *
          * Currently, that is only used for `provideDelegate` resolution, see
          * [org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclarationsResolveTransformer.fixInnerVariablesForProvideDelegateIfNeeded]
          */
-        val typeVariablesThatAreNotCountedAsProperTypes: Set<TypeConstructorMarker>?
         val typeVariablesThatAreCountedAsProperTypes: Set<TypeConstructorMarker>?
 
         fun isReified(variable: TypeVariableMarker): Boolean
@@ -223,8 +221,7 @@
         val key = it.typeConstructor()
         if (!notFixedTypeVariables.containsKey(key)) return false
         if (typeVariablesThatAreCountedAsProperTypes != null && typeVariablesThatAreCountedAsProperTypes!!.contains(key)) return false
-        if (typeVariablesThatAreNotCountedAsProperTypes == null) return true
-        return typeVariablesThatAreNotCountedAsProperTypes!!.contains(key)
+        return true
     }
 
     private fun Context.isReified(variable: TypeConstructorMarker): Boolean =
diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt
index ac67170..c830f1c 100644
--- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt
+++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt
@@ -245,5 +245,10 @@
     override var outerSystemVariablesPrefixSize: Int = 0
 
     override var usesOuterCs: Boolean = false
-    var outerCS: ConstraintStorage? = null
+
+    @AssertionsOnly
+    internal var outerCS: ConstraintStorage? = null
 }
+
+@RequiresOptIn
+annotation class AssertionsOnly
\ No newline at end of file
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 a46c272..5e9ae32 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
@@ -41,7 +41,6 @@
     private val properTypesCache: MutableSet<KotlinTypeMarker> = SmartSet.create()
     private val notProperTypesCache: MutableSet<KotlinTypeMarker> = SmartSet.create()
     private val intersectionTypesCache: MutableMap<Collection<KotlinTypeMarker>, EmptyIntersectionTypeInfo?> = mutableMapOf()
-    override var typeVariablesThatAreNotCountedAsProperTypes: Set<TypeConstructorMarker>? = null
     override var typeVariablesThatAreCountedAsProperTypes: Set<TypeConstructorMarker>? = null
 
     private var couldBeResolvedWithUnrestrictedBuilderInference: Boolean = false
@@ -52,27 +51,6 @@
      * @see [org.jetbrains.kotlin.resolve.calls.inference.components.VariableFixationFinder.Context.typeVariablesThatAreNotCountedAsProperTypes]
      * @see [org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclarationsResolveTransformer.fixInnerVariablesForProvideDelegateIfNeeded]
      */
-    override fun <R> withTypeVariablesThatAreNotCountedAsProperTypes(typeVariables: Set<TypeConstructorMarker>, block: () -> R): R {
-        checkState(State.BUILDING)
-        // Cleaning cache is necessary because temporarily we change the meaning of what does "proper type" mean
-        properTypesCache.clear()
-        notProperTypesCache.clear()
-
-        require(typeVariablesThatAreNotCountedAsProperTypes == null) {
-            "Currently there should be no nested withDisallowingOnlyThisTypeVariablesForProperTypes calls"
-        }
-
-        typeVariablesThatAreNotCountedAsProperTypes = typeVariables
-
-        val result = block()
-
-        typeVariablesThatAreNotCountedAsProperTypes = null
-        properTypesCache.clear()
-        notProperTypesCache.clear()
-
-        return result
-    }
-
     override fun <R> withTypeVariablesThatAreCountedAsProperTypes(typeVariables: Set<TypeConstructorMarker>, block: () -> R): R {
         checkState(State.BUILDING)
         // Cleaning cache is necessary because temporarily we change the meaning of what does "proper type" mean
@@ -330,6 +308,7 @@
 
         storage.usesOuterCs = true
         storage.outerSystemVariablesPrefixSize = outerSystem.allTypeVariables.size
+        @OptIn(AssertionsOnly::class)
         storage.outerCS = outerSystem
 
         addOtherSystem(outerSystem, isAddingOuter = true)
@@ -339,6 +318,7 @@
         require(storage.allTypeVariables.isEmpty())
         storage.usesOuterCs = baseSystem.usesOuterCs
         storage.outerSystemVariablesPrefixSize = baseSystem.outerSystemVariablesPrefixSize
+        @OptIn(AssertionsOnly::class)
         storage.outerCS = (baseSystem as? MutableConstraintStorage)?.outerCS
 
         addOtherSystem(baseSystem)
@@ -366,6 +346,8 @@
             notProperTypesCache.clear()
         }
 
+        // `clearNotFixedTypeVariables` means that we're mostly replacing the content, thus we need to remove variables that have been fixed
+        // in `otherSystem` from `this.notFixedTypeVariables`, too
         if (clearNotFixedTypeVariables) {
             notFixedTypeVariables.clear()
         }
@@ -387,17 +369,24 @@
         storage.postponedTypeVariables.addAll(otherSystem.postponedTypeVariables)
         storage.constraintsFromAllForkPoints.addAll(otherSystem.constraintsFromAllForkPoints)
 
-        isAddingOuter.hashCode()
+        runOuterCSRelatedAssertions(otherSystem, isAddingOuter)
+    }
 
-//        if (otherSystem.usesOuterCs && (otherSystem as? MutableConstraintStorage)?.outerCS !== storage) {
-//            require(storage.usesOuterCs)
-//
-//            if (!isAddingOuter) {
-//                require(storage.outerSystemVariablesPrefixSize == otherSystem.outerSystemVariablesPrefixSize) {
-//                    "Expected to be ${otherSystem.outerSystemVariablesPrefixSize}, but ${storage.outerSystemVariablesPrefixSize} found"
-//                }
-//            }
-//        }
+
+    private fun runOuterCSRelatedAssertions(otherSystem: ConstraintStorage, isAddingOuter: Boolean) {
+        if (!otherSystem.usesOuterCs) return
+
+        // When integrating a child system back, it's ok that for root CS, `storage.usesOuterCs == false`
+        @OptIn(AssertionsOnly::class)
+        if ((otherSystem as? MutableConstraintStorage)?.outerCS === storage) return
+
+        require(storage.usesOuterCs)
+
+        if (!isAddingOuter) {
+            require(storage.outerSystemVariablesPrefixSize == otherSystem.outerSystemVariablesPrefixSize) {
+                "Expected to be ${otherSystem.outerSystemVariablesPrefixSize}, but ${storage.outerSystemVariablesPrefixSize} found"
+            }
+        }
     }
 
     // ResultTypeResolver.Context, ConstraintSystemBuilder
@@ -425,10 +414,6 @@
                 if (typeVariablesThatAreCountedAsProperTypes!!.contains(typeToCheck.typeConstructor())) return@contains false
             }
 
-            if (typeVariablesThatAreNotCountedAsProperTypes != null) {
-                return@contains typeVariablesThatAreNotCountedAsProperTypes!!.contains(typeToCheck.typeConstructor())
-            }
-
             if (!storage.allTypeVariables.containsKey(typeToCheck.typeConstructor())) return@contains false
 
             return@contains true
diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt
index 357f354..bc852b5 100644
--- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt
+++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt
@@ -79,7 +79,7 @@
                     )
                 }
             }
-            ConstraintSystemCompletionMode.PARTIAL, ConstraintSystemCompletionMode.ONLY_LAMBDAS, ConstraintSystemCompletionMode.PARTIAL_BI -> {
+            ConstraintSystemCompletionMode.PARTIAL, ConstraintSystemCompletionMode.PARTIAL_PCLA -> {
                 candidate.runCompletion(completionMode, diagnosticHolder, resolutionCallbacks)
                 candidate.asCallResolutionResult(completionMode, diagnosticHolder)
             }