Remove ConstraintSystem.partialSubstitutor, move logic to FuzzyType

This commit is contained in:
Alexander Udalov
2015-10-30 19:45:56 +03:00
parent d72a4c8037
commit 89dfd52363
3 changed files with 20 additions and 30 deletions
@@ -54,11 +54,6 @@ interface ConstraintSystem {
*/
val currentSubstitutor: TypeSubstitutor
/**
* Returns the substitution only for type parameters that have result values, otherwise returns the type parameter itself.
*/
val partialSubstitutor: TypeSubstitutor
fun getNestedTypeVariables(type: KotlinType): List<TypeParameterDescriptor>
fun toBuilder(filterConstraintPosition: (ConstraintPosition) -> Boolean = { true }): Builder
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.resolve.calls.inference
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl.ConstraintKind.EQUAL
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl.ConstraintKind.SUB_TYPE
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
@@ -25,7 +24,6 @@ import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.Constrain
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.TYPE_BOUND_POSITION
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.derivedFrom
import org.jetbrains.kotlin.resolve.descriptorUtil.hasOnlyInputTypesAnnotation
import org.jetbrains.kotlin.resolve.scopes.KtScope
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
@@ -84,27 +82,23 @@ class ConstraintSystemImpl(
private fun getParameterToInferredValueMap(
typeParameterBounds: Map<TypeParameterDescriptor, TypeBoundsImpl>,
getDefaultTypeProjection: (TypeParameterDescriptor) -> TypeProjection,
getDefaultType: (TypeParameterDescriptor) -> KotlinType,
substituteOriginal: Boolean
): Map<TypeParameterDescriptor, TypeProjection> {
val substitutionContext = HashMap<TypeParameterDescriptor, TypeProjection>()
for ((variable, typeBounds) in typeParameterBounds) {
val typeProjection: TypeProjection
val value = typeBounds.value
val typeParameter = if (substituteOriginal) variablesToOriginal[variable]!! else variable
if (value != null && !TypeUtils.containsSpecialType(value, DONT_CARE)) {
typeProjection = TypeProjectionImpl(value)
}
else {
typeProjection = getDefaultTypeProjection(typeParameter)
}
substitutionContext.put(typeParameter, typeProjection)
val type =
if (value != null && !TypeUtils.containsSpecialType(value, DONT_CARE)) value
else getDefaultType(typeParameter)
substitutionContext.put(typeParameter, TypeProjectionImpl(type))
}
return substitutionContext
}
private fun replaceUninferredBy(
getDefaultValue: (TypeParameterDescriptor) -> TypeProjection,
getDefaultValue: (TypeParameterDescriptor) -> KotlinType,
substituteOriginal: Boolean
): TypeSubstitutor {
val parameterToInferredValueMap = getParameterToInferredValueMap(allTypeParameterBounds, getDefaultValue, substituteOriginal)
@@ -131,22 +125,17 @@ class ConstraintSystemImpl(
}
override val resultingSubstitutor: TypeSubstitutor
get() = getSubstitutor(substituteOriginal = true) { TypeProjectionImpl(ErrorUtils.createUninferredParameterType(it)) }
get() = getSubstitutor(substituteOriginal = true) { ErrorUtils.createUninferredParameterType(it) }
override val currentSubstitutor: TypeSubstitutor
get() = getSubstitutor(substituteOriginal = true) { TypeProjectionImpl(TypeUtils.DONT_CARE) }
get() = getSubstitutor(substituteOriginal = true) { TypeUtils.DONT_CARE }
override val partialSubstitutor: TypeSubstitutor
get() = getSubstitutor(substituteOriginal = true) {
TypeProjectionImpl(KotlinTypeImpl.create(Annotations.EMPTY, it.typeConstructor, false, listOf(), KtScope.Empty))
}
private fun getSubstitutor(substituteOriginal: Boolean, getDefaultValue: (TypeParameterDescriptor) -> TypeProjection) =
private fun getSubstitutor(substituteOriginal: Boolean, getDefaultValue: (TypeParameterDescriptor) -> KotlinType) =
replaceUninferredBy(getDefaultValue, substituteOriginal).setApproximateCapturedTypes()
private fun satisfyInitialConstraints(): Boolean {
fun KotlinType.substitute(): KotlinType? {
val substitutor = getSubstitutor(substituteOriginal = false) { TypeProjectionImpl(ErrorUtils.createUninferredParameterType(it)) }
val substitutor = getSubstitutor(substituteOriginal = false) { ErrorUtils.createUninferredParameterType(it) }
return substitutor.substitute(this, Variance.INVARIANT) ?: return null
}
return initialConstraints.all {
@@ -22,9 +22,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.*
import java.util.*
@@ -138,6 +136,14 @@ class FuzzyType(
if (substitutedType.isError) return null
val otherSubstitutedType = substitutor.substitute(otherType.type, Variance.INVARIANT) ?: return null
if (otherSubstitutedType.isError) return null
return if (substitutedType.checkInheritance(otherSubstitutedType)) constraintSystem.partialSubstitutor else null
if (!substitutedType.checkInheritance(otherSubstitutedType)) return null
val substitution = constraintSystem.typeVariables.toMap({ it.typeConstructor }) {
val type = it.defaultType
val solution = substitutor.substitute(type, Variance.INVARIANT)
TypeProjectionImpl(if (solution != null && !ErrorUtils.containsUninferredParameter(solution)) solution else type)
}
return TypeSubstitutor.create(TypeConstructorSubstitution.createByConstructorsMap(substitution))
}
}