K2: Implement partially constrained lambda analysis (PCLA)

It's expected to partially mimic the behavior of what
previously was called builder inference, but with more clear contracts
(documentation is in progress, though)

See a lot of fixed issues in the later commits with test data,
especially [red-to-green]

^KT-59791 In Progress
This commit is contained in:
Denis.Zharkov
2023-08-21 17:51:54 +02:00
committed by Space Team
parent 9ae5287df8
commit 276f5b26d8
44 changed files with 1356 additions and 1086 deletions
@@ -10,22 +10,25 @@ import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
import org.jetbrains.kotlin.resolve.calls.components.candidate.ResolutionCandidate
import org.jetbrains.kotlin.resolve.calls.components.candidate.CallableReferenceResolutionCandidate
import org.jetbrains.kotlin.resolve.calls.components.candidate.ResolutionCandidate
import org.jetbrains.kotlin.resolve.calls.components.candidate.SimpleResolutionCandidate
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
import org.jetbrains.kotlin.resolve.calls.inference.addEqualityConstraintIfCompatible
import org.jetbrains.kotlin.resolve.calls.inference.components.*
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionMode
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutorByConstructorMap
import org.jetbrains.kotlin.resolve.calls.inference.components.TrivialConstraintTypeInferenceOracle
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage.Empty.hasContradiction
import org.jetbrains.kotlin.resolve.calls.inference.model.ExpectedTypeConstraintPositionImpl
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.tower.CandidateFactory
import org.jetbrains.kotlin.resolve.calls.tower.forceResolution
import org.jetbrains.kotlin.types.error.ErrorUtils
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.error.ErrorType
import org.jetbrains.kotlin.types.error.ErrorTypeKind
import org.jetbrains.kotlin.types.error.ErrorUtils
import org.jetbrains.kotlin.types.model.safeSubstitute
import org.jetbrains.kotlin.utils.addToStdlib.same
@@ -80,6 +83,7 @@ class KotlinCallCompleter(
candidate.runCompletion(completionMode, diagnosticHolder, resolutionCallbacks)
candidate.asCallResolutionResult(completionMode, diagnosticHolder)
}
ConstraintSystemCompletionMode.PCLA_POSTPONED_CALL -> error("PCLA might be only run for K2")
ConstraintSystemCompletionMode.UNTIL_FIRST_LAMBDA -> throw IllegalStateException("Should not be here")
}
@@ -12,7 +12,10 @@ import org.jetbrains.kotlin.resolve.calls.components.transformToResolvedLambda
import org.jetbrains.kotlin.resolve.calls.inference.model.*
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.model.MultiLambdaBuilderInferenceRestriction
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.KotlinTypeFactory
import org.jetbrains.kotlin.types.TypeConstructor
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.error.ErrorTypeKind
import org.jetbrains.kotlin.types.error.ErrorUtils
import org.jetbrains.kotlin.types.model.*
@@ -279,7 +282,7 @@ class KotlinConstraintSystemCompleter(
// 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
return variableForFixation?.isReady == true
}
private fun transformToAtomWithNewFunctionalExpectedType(
@@ -319,7 +322,7 @@ class KotlinConstraintSystemCompleter(
topLevelType
) ?: return false
if (!variableForFixation.hasProperConstraint) return false
if (!variableForFixation.isReady) return false
fixVariable(this, notFixedTypeVariables.getValue(variableForFixation.variable), topLevelAtoms, diagnosticsHolder)
@@ -340,7 +343,7 @@ class KotlinConstraintSystemCompleter(
postponedArguments, completionMode, topLevelType,
) ?: break
assert(!variableForFixation.hasProperConstraint) {
assert(!variableForFixation.isReady) {
"At this stage there should be no remaining variables with proper constraints"
}