K2: Do not fix variables that has yet unprocessed constraints in forks

Otherwise, exception from org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintInjector.TypeCheckerStateForConstraintInjector.fixedTypeVariable
might happen during forks resolution

The test data is extracted from intelliJ FP test

^KT-43296 Fixed
This commit is contained in:
Denis.Zharkov
2022-11-02 18:51:20 +01:00
committed by Space Team
parent b73acd7a3a
commit ca12cfb90d
8 changed files with 122 additions and 2 deletions
@@ -7,11 +7,13 @@ package org.jetbrains.kotlin.resolve.calls.inference.components
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.resolve.calls.inference.ForkPointData
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionMode.PARTIAL
import org.jetbrains.kotlin.resolve.calls.inference.hasRecursiveTypeParametersWithGivenSelfType
import org.jetbrains.kotlin.resolve.calls.inference.isRecursiveTypeParameter
import org.jetbrains.kotlin.resolve.calls.inference.model.Constraint
import org.jetbrains.kotlin.resolve.calls.inference.model.DeclaredUpperBoundConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.IncorporationConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.VariableWithConstraints
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
import org.jetbrains.kotlin.types.model.*
@@ -24,6 +26,8 @@ class VariableFixationFinder(
val notFixedTypeVariables: Map<TypeConstructorMarker, VariableWithConstraints>
val fixedTypeVariables: Map<TypeConstructorMarker, KotlinTypeMarker>
val postponedTypeVariables: List<TypeVariableMarker>
val constraintsFromAllForkPoints: MutableList<Pair<IncorporationConstraintPosition, ForkPointData>>
fun isReified(variable: TypeVariableMarker): Boolean
}
@@ -65,8 +69,9 @@ class VariableFixationFinder(
variable: TypeConstructorMarker,
dependencyProvider: TypeVariableDependencyInformationProvider,
): TypeVariableFixationReadiness = when {
!notFixedTypeVariables.contains(variable) ||
dependencyProvider.isVariableRelatedToTopLevelType(variable) -> TypeVariableFixationReadiness.FORBIDDEN
!notFixedTypeVariables.contains(variable) || dependencyProvider.isVariableRelatedToTopLevelType(variable) ||
variableHasUnprocessedConstraintsInForks(variable) ->
TypeVariableFixationReadiness.FORBIDDEN
isTypeInferenceForSelfTypesSupported && areAllProperConstraintsSelfTypeBased(variable) ->
TypeVariableFixationReadiness.READY_FOR_FIXATION_DECLARED_UPPER_BOUND_WITH_SELF_TYPES
!variableHasProperArgumentConstraints(variable) -> TypeVariableFixationReadiness.WITHOUT_PROPER_ARGUMENT_CONSTRAINT
@@ -85,6 +90,21 @@ class VariableFixationFinder(
else -> TypeVariableFixationReadiness.READY_FOR_FIXATION
}
private fun Context.variableHasUnprocessedConstraintsInForks(variableConstructor: TypeConstructorMarker): Boolean {
if (constraintsFromAllForkPoints.isEmpty()) return false
for ((_, forkPointData) in constraintsFromAllForkPoints) {
for (constraints in forkPointData) {
for ((typeVariableFromConstraint, constraint) in constraints) {
if (typeVariableFromConstraint.freshTypeConstructor() == variableConstructor) return true
if (containsTypeVariable(constraint.type, variableConstructor)) return true
}
}
}
return false
}
fun isTypeVariableHasProperConstraint(
context: Context,
typeVariable: TypeConstructorMarker,