[FE 1.0] Store constraint system in call resolution result instead of constraint storage

This commit is contained in:
Victor Petukhov
2021-12-24 12:52:51 +03:00
committed by teamcity
parent cedd98148c
commit 74f294d849
9 changed files with 35 additions and 22 deletions
@@ -438,10 +438,12 @@ class BuilderInferenceSession(
integrateConstraints(initialStorage, nonFixedToVariablesSubstitutor, false) integrateConstraints(initialStorage, nonFixedToVariablesSubstitutor, false)
for (call in commonCalls) { for (call in commonCalls) {
integrateConstraints(call.callResolutionResult.constraintSystem, nonFixedToVariablesSubstitutor, false) val storage = call.callResolutionResult.constraintSystem.getBuilder().currentStorage()
integrateConstraints(storage, nonFixedToVariablesSubstitutor, false)
} }
for (call in partiallyResolvedCallsInfo) { for (call in partiallyResolvedCallsInfo) {
integrateConstraints(call.callResolutionResult.constraintSystem, nonFixedToVariablesSubstitutor, true) val storage = call.callResolutionResult.constraintSystem.getBuilder().currentStorage()
integrateConstraints(storage, nonFixedToVariablesSubstitutor, true)
} }
return commonSystem.notFixedTypeVariables.all { it.value.constraints.isEmpty() } return commonSystem.notFixedTypeVariables.all { it.value.constraints.isEmpty() }
@@ -469,7 +471,8 @@ class BuilderInferenceSession(
nonFixedTypesToResultSubstitutor: NewTypeSubstitutor, nonFixedTypesToResultSubstitutor: NewTypeSubstitutor,
nonFixedTypesToResult: Map<TypeConstructor, UnwrappedType> nonFixedTypesToResult: Map<TypeConstructor, UnwrappedType>
) { ) {
val resultingCallSubstitutor = completedCall.callResolutionResult.constraintSystem.fixedTypeVariables.entries val storage = completedCall.callResolutionResult.constraintSystem.getBuilder().currentStorage()
val resultingCallSubstitutor = storage.fixedTypeVariables.entries
.associate { it.key to nonFixedTypesToResultSubstitutor.safeSubstitute(it.value as UnwrappedType) } // TODO: SUB .associate { it.key to nonFixedTypesToResultSubstitutor.safeSubstitute(it.value as UnwrappedType) } // TODO: SUB
val resultingSubstitutor = val resultingSubstitutor =
@@ -103,6 +103,9 @@ class KotlinResolutionCallbacksImpl(
) as KotlinType ) as KotlinType
} }
override fun createEmptyConstraintSystem(): NewConstraintSystem =
NewConstraintSystemImpl(callComponents.constraintInjector, callComponents.builtIns, callComponents.kotlinTypeRefiner)
override fun resolveCallableReferenceArgument( override fun resolveCallableReferenceArgument(
argument: CallableReferenceKotlinCallArgument, argument: CallableReferenceKotlinCallArgument,
expectedType: UnwrappedType?, expectedType: UnwrappedType?,
@@ -107,7 +107,8 @@ class KotlinToResolvedCallTransformer(
is CompletedCallResolutionResult, is ErrorCallResolutionResult -> { is CompletedCallResolutionResult, is ErrorCallResolutionResult -> {
val candidate = (baseResolvedCall as SingleCallResolutionResult).resultCallAtom val candidate = (baseResolvedCall as SingleCallResolutionResult).resultCallAtom
val resultSubstitutor = baseResolvedCall.constraintSystem.buildResultingSubstitutor(typeSystemContext) val resultSubstitutor =
baseResolvedCall.constraintSystem.getBuilder().currentStorage().buildResultingSubstitutor(typeSystemContext)
if (context.inferenceSession.writeOnlyStubs(baseResolvedCall)) { if (context.inferenceSession.writeOnlyStubs(baseResolvedCall)) {
val stub = createStubResolvedCallAndWriteItToTrace<CallableDescriptor>( val stub = createStubResolvedCallAndWriteItToTrace<CallableDescriptor>(
candidate, candidate,
@@ -541,7 +541,7 @@ class PSICallResolver(
val psiKotlinCall = variable.resolvedCall.atom.psiKotlinCall val psiKotlinCall = variable.resolvedCall.atom.psiKotlinCall
val variableResult = PartialCallResolutionResult(variable.resolvedCall, listOf(), variable.getSystem().asReadOnlyStorage()) val variableResult = PartialCallResolutionResult(variable.resolvedCall, listOf(), variable.getSystem())
return SubKotlinCallArgumentImpl( return SubKotlinCallArgumentImpl(
CallMaker.makeExternalValueArgument((variableReceiver.receiverValue as ExpressionReceiver).expression), CallMaker.makeExternalValueArgument((variableReceiver.receiverValue as ExpressionReceiver).expression),
@@ -65,7 +65,8 @@ abstract class StubTypesBasedInferenceSession<D : CallableDescriptor>(
} }
override fun currentConstraintSystem(): ConstraintStorage { override fun currentConstraintSystem(): ConstraintStorage {
return partiallyResolvedCallsInfo.lastOrNull()?.callResolutionResult?.constraintSystem ?: ConstraintStorage.Empty return partiallyResolvedCallsInfo.lastOrNull()?.callResolutionResult?.constraintSystem?.getBuilder()?.currentStorage()
?: ConstraintStorage.Empty
} }
override fun callCompleted(resolvedAtom: ResolvedAtom): Boolean = override fun callCompleted(resolvedAtom: ResolvedAtom): Boolean =
@@ -116,7 +117,7 @@ abstract class StubTypesBasedInferenceSession<D : CallableDescriptor>(
for (callInfo in listOf(goodCandidate, badCandidate)) { for (callInfo in listOf(goodCandidate, badCandidate)) {
val atomsToAnalyze = mutableListOf<ResolvedAtom>(callInfo.callResolutionResult) val atomsToAnalyze = mutableListOf<ResolvedAtom>(callInfo.callResolutionResult)
val system = NewConstraintSystemImpl(callComponents.constraintInjector, builtIns, callComponents.kotlinTypeRefiner).apply { val system = NewConstraintSystemImpl(callComponents.constraintInjector, builtIns, callComponents.kotlinTypeRefiner).apply {
addOtherSystem(callInfo.callResolutionResult.constraintSystem) addOtherSystem(callInfo.callResolutionResult.constraintSystem.getBuilder().currentStorage())
/* /*
* This is needed for very stupid case, when we have some delegate with good `getValue` and bad `setValue` that * This is needed for very stupid case, when we have some delegate with good `getValue` and bad `setValue` that
* was provided by some function call with generic (e.g. var x by lazy { "" }) * was provided by some function call with generic (e.g. var x by lazy { "" })
@@ -129,7 +130,8 @@ abstract class StubTypesBasedInferenceSession<D : CallableDescriptor>(
* stub atoms in order to call completer doesn't fail * stub atoms in order to call completer doesn't fail
*/ */
if (callInfo === badCandidate) { if (callInfo === badCandidate) {
for ((typeVariable, fixedType) in allCandidates[0].resolutionResult.constraintSystem.fixedTypeVariables) { val storage = allCandidates[0].resolutionResult.constraintSystem.getBuilder().currentStorage()
for ((typeVariable, fixedType) in storage.fixedTypeVariables) {
if (typeVariable in this.notFixedTypeVariables) { if (typeVariable in this.notFixedTypeVariables) {
val type = (typeVariable as TypeConstructor).typeForTypeVariable() val type = (typeVariable as TypeConstructor).typeForTypeVariable()
addEqualityConstraint( addEqualityConstraint(
@@ -178,7 +180,7 @@ abstract class StubTypesBasedInferenceSession<D : CallableDescriptor>(
commonSystem: NewConstraintSystem commonSystem: NewConstraintSystem
): CallResolutionResult { ): CallResolutionResult {
val diagnostics = diagnosticsHolder.getDiagnostics() + callResolutionResult.diagnostics + commonSystem.errors.asDiagnostics() val diagnostics = diagnosticsHolder.getDiagnostics() + callResolutionResult.diagnostics + commonSystem.errors.asDiagnostics()
return CompletedCallResolutionResult(callResolutionResult.resultCallAtom, diagnostics, commonSystem.asReadOnlyStorage()) return CompletedCallResolutionResult(callResolutionResult.resultCallAtom, diagnostics, commonSystem)
} }
} }
@@ -98,6 +98,8 @@ interface KotlinResolutionCallbacks {
fun findResultType(constraintSystem: NewConstraintSystem, typeVariable: TypeVariableTypeConstructor): KotlinType? fun findResultType(constraintSystem: NewConstraintSystem, typeVariable: TypeVariableTypeConstructor): KotlinType?
fun createEmptyConstraintSystem(): NewConstraintSystem
fun bindStubResolvedCallForCandidate(candidate: ResolvedCallAtom) fun bindStubResolvedCallForCandidate(candidate: ResolvedCallAtom)
fun isCompileTimeConstant(resolvedAtom: ResolvedCallAtom, expectedType: UnwrappedType): Boolean fun isCompileTimeConstant(resolvedAtom: ResolvedCallAtom, expectedType: UnwrappedType): Boolean
@@ -228,7 +228,7 @@ class KotlinCallCompleter(
CandidateWithDiagnostics(candidate, diagnosticsHolder.getDiagnostics() + candidate.diagnostics) CandidateWithDiagnostics(candidate, diagnosticsHolder.getDiagnostics() + candidate.diagnostics)
} }
return AllCandidatesResolutionResult(completedCandidates) return AllCandidatesResolutionResult(completedCandidates, resolutionCallbacks.createEmptyConstraintSystem())
} }
private fun ResolutionCandidate.runCompletion( private fun ResolutionCandidate.runCompletion(
@@ -350,17 +350,17 @@ class KotlinCallCompleter(
diagnosticsHolder: KotlinDiagnosticsHolder.SimpleHolder, diagnosticsHolder: KotlinDiagnosticsHolder.SimpleHolder,
forwardToInferenceSession: Boolean = false forwardToInferenceSession: Boolean = false
): CallResolutionResult { ): CallResolutionResult {
val systemStorage = getSystem().asReadOnlyStorage() val constraintSystem = getSystem()
val allDiagnostics = diagnosticsHolder.getDiagnostics() + diagnostics val allDiagnostics = diagnosticsHolder.getDiagnostics() + diagnostics
if (isErrorCandidate()) { if (isErrorCandidate()) {
return ErrorCallResolutionResult(resolvedCall, allDiagnostics, systemStorage) return ErrorCallResolutionResult(resolvedCall, allDiagnostics, constraintSystem)
} }
return if (type == ConstraintSystemCompletionMode.FULL) { return if (type == ConstraintSystemCompletionMode.FULL) {
CompletedCallResolutionResult(resolvedCall, allDiagnostics, systemStorage) CompletedCallResolutionResult(resolvedCall, allDiagnostics, constraintSystem)
} else { } else {
PartialCallResolutionResult(resolvedCall, allDiagnostics, systemStorage, forwardToInferenceSession) PartialCallResolutionResult(resolvedCall, allDiagnostics, constraintSystem, forwardToInferenceSession)
} }
} }
} }
@@ -70,7 +70,7 @@ fun CallableDescriptor.substituteAndApproximateTypes(
fun PostponedArgumentsAnalyzerContext.addSubsystemFromArgument(argument: KotlinCallArgument?): Boolean { fun PostponedArgumentsAnalyzerContext.addSubsystemFromArgument(argument: KotlinCallArgument?): Boolean {
return when (argument) { return when (argument) {
is SubKotlinCallArgument -> { is SubKotlinCallArgument -> {
addOtherSystem(argument.callResult.constraintSystem) addOtherSystem(argument.callResult.constraintSystem.getBuilder().currentStorage())
true true
} }
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.*
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.components.candidate.ResolutionCandidate 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.CallableReferenceResolutionCandidate
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeConstructor import org.jetbrains.kotlin.types.TypeConstructor
@@ -252,7 +253,7 @@ class ResolvedCollectionLiteralAtom(
sealed class CallResolutionResult( sealed class CallResolutionResult(
resultCallAtom: ResolvedCallAtom?, resultCallAtom: ResolvedCallAtom?,
val diagnostics: List<KotlinCallDiagnostic>, val diagnostics: List<KotlinCallDiagnostic>,
val constraintSystem: ConstraintStorage val constraintSystem: NewConstraintSystem
) : ResolvedAtom() { ) : ResolvedAtom() {
init { init {
setAnalyzedResults(listOfNotNull(resultCallAtom)) setAnalyzedResults(listOfNotNull(resultCallAtom))
@@ -283,31 +284,32 @@ sealed class CallResolutionResult(
open class SingleCallResolutionResult( open class SingleCallResolutionResult(
val resultCallAtom: ResolvedCallAtom, val resultCallAtom: ResolvedCallAtom,
diagnostics: List<KotlinCallDiagnostic>, diagnostics: List<KotlinCallDiagnostic>,
constraintSystem: ConstraintStorage constraintSystem: NewConstraintSystem
) : CallResolutionResult(resultCallAtom, diagnostics, constraintSystem) ) : CallResolutionResult(resultCallAtom, diagnostics, constraintSystem)
class PartialCallResolutionResult( class PartialCallResolutionResult(
resultCallAtom: ResolvedCallAtom, resultCallAtom: ResolvedCallAtom,
diagnostics: List<KotlinCallDiagnostic>, diagnostics: List<KotlinCallDiagnostic>,
constraintSystem: ConstraintStorage, constraintSystem: NewConstraintSystem,
val forwardToInferenceSession: Boolean = false val forwardToInferenceSession: Boolean = false
) : SingleCallResolutionResult(resultCallAtom, diagnostics, constraintSystem) ) : SingleCallResolutionResult(resultCallAtom, diagnostics, constraintSystem)
class CompletedCallResolutionResult( class CompletedCallResolutionResult(
resultCallAtom: ResolvedCallAtom, resultCallAtom: ResolvedCallAtom,
diagnostics: List<KotlinCallDiagnostic>, diagnostics: List<KotlinCallDiagnostic>,
constraintSystem: ConstraintStorage constraintSystem: NewConstraintSystem
) : SingleCallResolutionResult(resultCallAtom, diagnostics, constraintSystem) ) : SingleCallResolutionResult(resultCallAtom, diagnostics, constraintSystem)
class ErrorCallResolutionResult( class ErrorCallResolutionResult(
resultCallAtom: ResolvedCallAtom, resultCallAtom: ResolvedCallAtom,
diagnostics: List<KotlinCallDiagnostic>, diagnostics: List<KotlinCallDiagnostic>,
constraintSystem: ConstraintStorage constraintSystem: NewConstraintSystem
) : SingleCallResolutionResult(resultCallAtom, diagnostics, constraintSystem) ) : SingleCallResolutionResult(resultCallAtom, diagnostics, constraintSystem)
class AllCandidatesResolutionResult( class AllCandidatesResolutionResult(
val allCandidates: Collection<CandidateWithDiagnostics> val allCandidates: Collection<CandidateWithDiagnostics>,
) : CallResolutionResult(null, emptyList(), ConstraintStorage.Empty) constraintSystem: NewConstraintSystem
) : CallResolutionResult(null, emptyList(), constraintSystem)
data class CandidateWithDiagnostics(val candidate: ResolutionCandidate, val diagnostics: List<KotlinCallDiagnostic>) data class CandidateWithDiagnostics(val candidate: ResolutionCandidate, val diagnostics: List<KotlinCallDiagnostic>)