First steps to make distinction between variables and descriptors in ConstraintSystem
A type variable is an entity, the value of which should be solved by the system; a descriptor is an actual TypeParameterDescriptor declaration
This commit is contained in:
@@ -225,7 +225,7 @@ public object Renderers {
|
||||
inferenceErrorData: InferenceErrorData, result: TabledDescriptorRenderer
|
||||
): TabledDescriptorRenderer {
|
||||
var firstUnknownParameter: TypeParameterDescriptor? = null
|
||||
for (typeParameter in inferenceErrorData.constraintSystem.typeVariables) {
|
||||
for (typeParameter in inferenceErrorData.constraintSystem.typeParameterDescriptors) {
|
||||
if (inferenceErrorData.constraintSystem.getTypeBounds(typeParameter).values.isEmpty()) {
|
||||
firstUnknownParameter = typeParameter
|
||||
break
|
||||
@@ -362,7 +362,7 @@ public object Renderers {
|
||||
public val RENDER_COLLECTION_OF_TYPES: Renderer<Collection<KotlinType>> = Renderer { renderTypes(it) }
|
||||
|
||||
private fun renderConstraintSystem(constraintSystem: ConstraintSystem, renderTypeBounds: Renderer<TypeBounds>): String {
|
||||
val typeVariables = constraintSystem.typeVariables
|
||||
val typeVariables = constraintSystem.typeParameterDescriptors
|
||||
val typeBounds = linkedSetOf<TypeBounds>()
|
||||
for (variable in typeVariables) {
|
||||
typeBounds.add(constraintSystem.getTypeBounds(variable))
|
||||
|
||||
+14
-9
@@ -24,18 +24,23 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
|
||||
interface ConstraintSystem {
|
||||
/**
|
||||
* Returns a set of all non-external registered type variables.
|
||||
*/
|
||||
val typeVariables: Set<TypeParameterDescriptor>
|
||||
|
||||
val status: ConstraintSystemStatus
|
||||
|
||||
/**
|
||||
* Returns the resulting type constraints of solving the constraint system for specific type variable.
|
||||
* Throws IllegalArgumentException if the type variable was not registered.
|
||||
* Returns a set of all non-external type parameter descriptors.
|
||||
*/
|
||||
fun getTypeBounds(typeVariable: TypeParameterDescriptor): TypeBounds
|
||||
val typeParameterDescriptors: Set<TypeParameterDescriptor>
|
||||
|
||||
/**
|
||||
* Returns a set of all registered type variables.
|
||||
*/
|
||||
val typeVariables: Set<TypeParameterDescriptor>
|
||||
|
||||
/**
|
||||
* Returns the resulting type constraints of solving the constraint system for specific type parameter descriptor.
|
||||
* Throws IllegalArgumentException if the type parameter descriptor is not known to the system.
|
||||
*/
|
||||
fun getTypeBounds(descriptor: TypeParameterDescriptor): TypeBounds
|
||||
|
||||
/**
|
||||
* Returns the result of solving the constraint system (mapping from the type variable to the resulting type projection).
|
||||
@@ -65,7 +70,7 @@ interface ConstraintSystem {
|
||||
*/
|
||||
fun registerTypeVariables(
|
||||
typeVariables: Collection<TypeParameterDescriptor>,
|
||||
mapToOriginal: (TypeParameterDescriptor) -> TypeParameterDescriptor = { it },
|
||||
mapToDescriptor: (TypeParameterDescriptor) -> TypeParameterDescriptor = { it },
|
||||
external: Boolean = false
|
||||
)
|
||||
|
||||
|
||||
+18
-20
@@ -54,15 +54,15 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
||||
internal val usedInBounds = HashMap<TypeParameterDescriptor, MutableList<TypeBounds.Bound>>()
|
||||
internal val errors = ArrayList<ConstraintError>()
|
||||
internal val initialConstraints = ArrayList<Constraint>()
|
||||
internal val originalToVariables = LinkedHashMap<TypeParameterDescriptor, TypeParameterDescriptor>()
|
||||
internal val variablesToOriginal = LinkedHashMap<TypeParameterDescriptor, TypeParameterDescriptor>()
|
||||
internal val descriptorToVariable = LinkedHashMap<TypeParameterDescriptor, TypeParameterDescriptor>()
|
||||
internal val variableToDescriptor = LinkedHashMap<TypeParameterDescriptor, TypeParameterDescriptor>()
|
||||
|
||||
private val originalToVariablesSubstitutor: TypeSubstitutor by lazy {
|
||||
private val descriptorToVariableSubstitutor: TypeSubstitutor by lazy {
|
||||
TypeSubstitutor.create(object : TypeConstructorSubstitution() {
|
||||
override fun get(key: TypeConstructor): TypeProjection? {
|
||||
val descriptor = key.declarationDescriptor
|
||||
if (descriptor !is TypeParameterDescriptor) return null
|
||||
val typeParameterDescriptor = originalToVariables[descriptor] ?: return null
|
||||
val typeParameterDescriptor = descriptorToVariable[descriptor] ?: return null
|
||||
return TypeProjectionImpl(typeParameterDescriptor.defaultType)
|
||||
}
|
||||
})
|
||||
@@ -70,16 +70,16 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
||||
|
||||
override fun registerTypeVariables(
|
||||
typeVariables: Collection<TypeParameterDescriptor>,
|
||||
mapToOriginal: (TypeParameterDescriptor) -> TypeParameterDescriptor,
|
||||
mapToDescriptor: (TypeParameterDescriptor) -> TypeParameterDescriptor,
|
||||
external: Boolean
|
||||
) {
|
||||
if (external) externalTypeParameters.addAll(typeVariables)
|
||||
|
||||
for (typeVariable in typeVariables) {
|
||||
allTypeParameterBounds.put(typeVariable, TypeBoundsImpl(typeVariable))
|
||||
val original = mapToOriginal(typeVariable)
|
||||
originalToVariables[original] = typeVariable
|
||||
variablesToOriginal[typeVariable] = original
|
||||
val descriptor = mapToDescriptor(typeVariable)
|
||||
descriptorToVariable[descriptor] = typeVariable
|
||||
variableToDescriptor[typeVariable] = descriptor
|
||||
}
|
||||
for ((typeVariable, typeBounds) in allTypeParameterBounds) {
|
||||
for (declaredUpperBound in typeVariable.upperBounds) {
|
||||
@@ -102,18 +102,18 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
||||
internal fun getNestedTypeVariables(type: KotlinType, original: Boolean): List<TypeParameterDescriptor> {
|
||||
return type.getNestedArguments().map { typeProjection ->
|
||||
typeProjection.type.constructor.declarationDescriptor as? TypeParameterDescriptor
|
||||
}.filterNotNull().filter { if (original) it in originalToVariables.keys else isMyTypeVariable(it) }
|
||||
}.filterNotNull().filter { if (original) it in descriptorToVariable.keys else isMyTypeVariable(it) }
|
||||
}
|
||||
|
||||
override fun addSupertypeConstraint(constrainingType: KotlinType?, subjectType: KotlinType, constraintPosition: ConstraintPosition) {
|
||||
if (constrainingType != null && TypeUtils.noExpectedType(constrainingType)) return
|
||||
|
||||
val newSubjectType = originalToVariablesSubstitutor.substitute(subjectType, Variance.INVARIANT)
|
||||
val newSubjectType = descriptorToVariableSubstitutor.substitute(subjectType, Variance.INVARIANT)
|
||||
addConstraint(SUB_TYPE, newSubjectType, constrainingType, ConstraintContext(constraintPosition, initial = true))
|
||||
}
|
||||
|
||||
override fun addSubtypeConstraint(constrainingType: KotlinType?, subjectType: KotlinType, constraintPosition: ConstraintPosition) {
|
||||
val newSubjectType = originalToVariablesSubstitutor.substitute(subjectType, Variance.INVARIANT)
|
||||
val newSubjectType = descriptorToVariableSubstitutor.substitute(subjectType, Variance.INVARIANT)
|
||||
addConstraint(SUB_TYPE, constrainingType, newSubjectType, ConstraintContext(constraintPosition, initial = true))
|
||||
}
|
||||
|
||||
@@ -332,15 +332,13 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
||||
|
||||
internal fun getBoundsUsedIn(typeVariable: TypeParameterDescriptor): List<Bound> = usedInBounds[typeVariable] ?: emptyList()
|
||||
|
||||
internal fun getTypeBounds(typeVariable: TypeParameterDescriptor): TypeBoundsImpl {
|
||||
val variableForOriginal = originalToVariables[typeVariable]
|
||||
if (variableForOriginal != null && variableForOriginal != typeVariable) {
|
||||
return getTypeBounds(variableForOriginal)
|
||||
internal fun getTypeBounds(descriptor: TypeParameterDescriptor): TypeBoundsImpl {
|
||||
val variable = descriptorToVariable[descriptor]
|
||||
if (variable != null && variable != descriptor) {
|
||||
return getTypeBounds(variable)
|
||||
}
|
||||
if (!isMyTypeVariable(typeVariable)) {
|
||||
throw IllegalArgumentException("TypeParameterDescriptor is not a type variable for constraint system: $typeVariable")
|
||||
}
|
||||
return allTypeParameterBounds[typeVariable]!!
|
||||
return allTypeParameterBounds[descriptor] ?:
|
||||
throw IllegalArgumentException("TypeParameterDescriptor is not a type variable for constraint system: $descriptor")
|
||||
}
|
||||
|
||||
private fun isMyTypeVariable(typeVariable: TypeParameterDescriptor) = allTypeParameterBounds.contains(typeVariable)
|
||||
@@ -378,7 +376,7 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
||||
|
||||
override fun build(): ConstraintSystem {
|
||||
return ConstraintSystemImpl(allTypeParameterBounds, externalTypeParameters, usedInBounds, errors, initialConstraints,
|
||||
originalToVariables, variablesToOriginal)
|
||||
descriptorToVariable, variableToDescriptor)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+17
-14
@@ -41,8 +41,8 @@ internal class ConstraintSystemImpl(
|
||||
private val usedInBounds: Map<TypeParameterDescriptor, MutableList<TypeBounds.Bound>>,
|
||||
private val errors: List<ConstraintError>,
|
||||
private val initialConstraints: List<ConstraintSystemBuilderImpl.Constraint>,
|
||||
private val originalToVariables: Map<TypeParameterDescriptor, TypeParameterDescriptor>,
|
||||
private val variablesToOriginal: Map<TypeParameterDescriptor, TypeParameterDescriptor>
|
||||
private val descriptorToVariable: Map<TypeParameterDescriptor, TypeParameterDescriptor>,
|
||||
private val variableToDescriptor: Map<TypeParameterDescriptor, TypeParameterDescriptor>
|
||||
) : ConstraintSystem {
|
||||
private val localTypeParameterBounds: Map<TypeParameterDescriptor, TypeBoundsImpl>
|
||||
get() = if (externalTypeParameters.isEmpty()) allTypeParameterBounds
|
||||
@@ -92,7 +92,7 @@ internal class ConstraintSystemImpl(
|
||||
val substitutionContext = HashMap<TypeParameterDescriptor, TypeProjection>()
|
||||
for ((variable, typeBounds) in typeParameterBounds) {
|
||||
val value = typeBounds.value
|
||||
val typeParameter = if (substituteOriginal) variablesToOriginal[variable]!! else variable
|
||||
val typeParameter = if (substituteOriginal) variableToDescriptor[variable]!! else variable
|
||||
val type =
|
||||
if (value != null && !TypeUtils.containsSpecialType(value, DONT_CARE)) value
|
||||
else getDefaultType(typeParameter)
|
||||
@@ -113,19 +113,22 @@ internal class ConstraintSystemImpl(
|
||||
override fun getNestedTypeVariables(type: KotlinType): List<TypeParameterDescriptor> {
|
||||
return type.getNestedArguments().map { typeProjection ->
|
||||
typeProjection.type.constructor.declarationDescriptor as? TypeParameterDescriptor
|
||||
}.filterNotNull().filter { it in typeVariables }
|
||||
}.filterNotNull().filter { it in typeParameterDescriptors }
|
||||
}
|
||||
|
||||
override val typeVariables: Set<TypeParameterDescriptor>
|
||||
get() = originalToVariables.keys
|
||||
override val typeParameterDescriptors: Set<TypeParameterDescriptor>
|
||||
get() = descriptorToVariable.keys
|
||||
|
||||
override fun getTypeBounds(typeVariable: TypeParameterDescriptor): TypeBoundsImpl {
|
||||
val variableForOriginal = originalToVariables[typeVariable]
|
||||
if (variableForOriginal != null && variableForOriginal != typeVariable) {
|
||||
return getTypeBounds(variableForOriginal)
|
||||
override val typeVariables: Set<TypeParameterDescriptor>
|
||||
get() = variableToDescriptor.keys
|
||||
|
||||
override fun getTypeBounds(descriptor: TypeParameterDescriptor): TypeBoundsImpl {
|
||||
val variable = descriptorToVariable[descriptor]
|
||||
if (variable != null && variable != descriptor) {
|
||||
return getTypeBounds(variable)
|
||||
}
|
||||
return allTypeParameterBounds[typeVariable] ?:
|
||||
throw IllegalArgumentException("TypeParameterDescriptor is not a type variable for constraint system: $typeVariable")
|
||||
return allTypeParameterBounds[descriptor] ?:
|
||||
throw IllegalArgumentException("TypeParameterDescriptor is not a type variable for constraint system: $descriptor")
|
||||
}
|
||||
|
||||
override val resultingSubstitutor: TypeSubstitutor
|
||||
@@ -176,8 +179,8 @@ internal class ConstraintSystemImpl(
|
||||
result.errors.addAll(errors.filter { filterConstraintPosition(it.constraintPosition) })
|
||||
|
||||
result.initialConstraints.addAll(initialConstraints.filter { filterConstraintPosition(it.position) })
|
||||
result.originalToVariables.putAll(originalToVariables)
|
||||
result.variablesToOriginal.putAll(variablesToOriginal)
|
||||
result.descriptorToVariable.putAll(descriptorToVariable)
|
||||
result.variableToDescriptor.putAll(variableToDescriptor)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
+4
-3
@@ -31,7 +31,7 @@ import java.util.*;
|
||||
public class ConstraintsUtil {
|
||||
@Nullable
|
||||
public static TypeParameterDescriptor getFirstConflictingParameter(@NotNull ConstraintSystem constraintSystem) {
|
||||
for (TypeParameterDescriptor typeParameter : constraintSystem.getTypeVariables()) {
|
||||
for (TypeParameterDescriptor typeParameter : constraintSystem.getTypeParameterDescriptors()) {
|
||||
TypeBounds constraints = constraintSystem.getTypeBounds(typeParameter);
|
||||
if (constraints.getValues().size() > 1) {
|
||||
return typeParameter;
|
||||
@@ -54,7 +54,7 @@ public class ConstraintsUtil {
|
||||
substitutionContexts.add(context);
|
||||
}
|
||||
|
||||
for (TypeParameterDescriptor typeParameter : constraintSystem.getTypeVariables()) {
|
||||
for (TypeParameterDescriptor typeParameter : constraintSystem.getTypeParameterDescriptors()) {
|
||||
if (typeParameter == firstConflictingParameter) continue;
|
||||
|
||||
KotlinType safeType = getSafeValue(constraintSystem, typeParameter);
|
||||
@@ -88,7 +88,8 @@ public class ConstraintsUtil {
|
||||
KotlinType type = constraintSystem.getTypeBounds(typeParameter).getValue();
|
||||
if (type == null) return true;
|
||||
for (KotlinType upperBound : typeParameter.getUpperBounds()) {
|
||||
if (!substituteOtherTypeParametersInBound && TypeUtils.dependsOnTypeParameters(upperBound, constraintSystem.getTypeVariables())) {
|
||||
if (!substituteOtherTypeParametersInBound &&
|
||||
TypeUtils.dependsOnTypeParameters(upperBound, constraintSystem.getTypeParameterDescriptors())) {
|
||||
continue;
|
||||
}
|
||||
KotlinType substitutedUpperBound = constraintSystem.getResultingSubstitutor().substitute(upperBound, Variance.INVARIANT);
|
||||
|
||||
@@ -138,7 +138,7 @@ class FuzzyType(
|
||||
if (otherSubstitutedType.isError) return null
|
||||
if (!substitutedType.checkInheritance(otherSubstitutedType)) return null
|
||||
|
||||
val substitution = constraintSystem.typeVariables.toMap({ it.typeConstructor }) {
|
||||
val substitution = constraintSystem.typeParameterDescriptors.toMap({ it.typeConstructor }) {
|
||||
val type = it.defaultType
|
||||
val solution = substitutor.substitute(type, Variance.INVARIANT)
|
||||
TypeProjectionImpl(if (solution != null && !ErrorUtils.containsUninferredParameter(solution)) solution else type)
|
||||
|
||||
Reference in New Issue
Block a user