diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt index 7e011158e1b..05dc70c1d82 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt @@ -320,7 +320,7 @@ public object Renderers { return result } - val typeParameter = system.variableToDescriptor(typeVariableWithCapturedConstraint) + val typeParameter = typeVariableWithCapturedConstraint.originalTypeParameter val explanation: String val upperBound = TypeIntersector.getUpperBoundsAsType(typeParameter) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystem.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystem.kt index 4d60b0fd70b..d235ae2c4b0 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystem.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystem.kt @@ -36,8 +36,6 @@ interface ConstraintSystem { fun descriptorToVariable(descriptor: TypeParameterDescriptor): TypeVariable - fun variableToDescriptor(typeVariable: TypeVariable): 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. diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilderImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilderImpl.kt index c8bde492eaf..dc8d364f63d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilderImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilderImpl.kt @@ -33,6 +33,7 @@ import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure import org.jetbrains.kotlin.types.checker.TypeCheckingProcedureCallbacks import org.jetbrains.kotlin.types.typeUtil.builtIns +import org.jetbrains.kotlin.types.typeUtil.defaultProjections import org.jetbrains.kotlin.types.typeUtil.isDefaultBound import java.util.* @@ -51,7 +52,6 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder { internal val errors = ArrayList() internal val initialConstraints = ArrayList() internal val descriptorToVariable = LinkedHashMap() - internal val variableToDescriptor = LinkedHashMap() private val descriptorToVariableSubstitutor: TypeSubstitutor by lazy { TypeSubstitutor.create(object : TypeConstructorSubstitution() { @@ -74,26 +74,26 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder { DescriptorSubstitutor.substituteTypeParameters( typeParameters.toList(), TypeSubstitution.EMPTY, typeParameters.first().containingDeclaration, this ) - }).map { typeParameter -> - TypeVariable(typeParameter, external) + }).zip(typeParameters).map { + val (fresh, original) = it + TypeVariable(fresh, original, external) } for ((descriptor, typeVariable) in typeParameters.zip(typeVariables)) { allTypeParameterBounds.put(typeVariable, TypeBoundsImpl(typeVariable)) descriptorToVariable[descriptor] = typeVariable - variableToDescriptor[typeVariable] = descriptor } for ((typeVariable, typeBounds) in allTypeParameterBounds) { for (declaredUpperBound in typeVariable.freshTypeParameter.upperBounds) { if (declaredUpperBound.isDefaultBound()) continue //todo remove this line (?) - val context = ConstraintContext(TYPE_BOUND_POSITION.position(typeVariable.freshTypeParameter.index)) + val context = ConstraintContext(TYPE_BOUND_POSITION.position(typeVariable.originalTypeParameter.index)) addBound(typeVariable, declaredUpperBound, UPPER_BOUND, context) } } return TypeSubstitutor.create(TypeConstructorSubstitution.createByParametersMap( - typeParameters.zip(TypeUtils.getDefaultTypeProjections(typeVariables.map { it.freshTypeParameter })).toMap() + typeParameters.zip(typeVariables.map { it.type }.defaultProjections()).toMap() )) } @@ -101,12 +101,8 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder { type -> type.constructor.declarationDescriptor.let { it is TypeParameterDescriptor && isMyTypeVariable(it) } } - internal fun getNestedTypeVariables(type: KotlinType): List { - val allTypeVariables = allTypeParameterBounds.keys - return type.getNestedTypeParameters().map { nestedTypeParameter -> - allTypeVariables.find { it.freshTypeParameter == nestedTypeParameter } - }.filterNotNull() - } + internal fun getNestedTypeVariables(type: KotlinType): List = + type.getNestedTypeParameters().map { getMyTypeVariable(it) }.filterNotNull() override fun addSupertypeConstraint(constrainingType: KotlinType?, subjectType: KotlinType, constraintPosition: ConstraintPosition) { val newSubjectType = descriptorToVariableSubstitutor.substitute(subjectType, Variance.INVARIANT) @@ -317,7 +313,7 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder { constraintContext: ConstraintContext, isTypeMarkedNullable: Boolean ) { - if (!typeVariable.freshTypeParameter.upperBounds.let { it.size == 1 && it.single().isDefaultBound() } && + if (!typeVariable.originalTypeParameter.upperBounds.let { it.size == 1 && it.single().isDefaultBound() } && constrainingTypeProjection.projectionKind == Variance.IN_VARIANCE) { errors.add(CannotCapture(constraintContext.position, typeVariable)) } @@ -339,17 +335,18 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder { } private fun isMyTypeVariable(typeParameter: TypeParameterDescriptor) = - allTypeParameterBounds.keys.any { it.freshTypeParameter == typeParameter } + getMyTypeVariable(typeParameter) != null - internal fun isMyTypeVariable(type: KotlinType): Boolean = getMyTypeVariable(type) != null + internal fun isMyTypeVariable(type: KotlinType): Boolean = + getMyTypeVariable(type) != null internal fun getMyTypeVariable(type: KotlinType): TypeVariable? { - val typeParameterDescriptor = type.constructor.declarationDescriptor as? TypeParameterDescriptor - return if (typeParameterDescriptor != null) - allTypeParameterBounds.keys.find { it.freshTypeParameter == typeParameterDescriptor } - else null + return getMyTypeVariable(type.constructor.declarationDescriptor as? TypeParameterDescriptor ?: return null) } + private fun getMyTypeVariable(typeParameter: TypeParameterDescriptor): TypeVariable? = + allTypeParameterBounds.keys.find { it.freshTypeParameter == typeParameter } + private fun storeInitialConstraint(constraintKind: ConstraintKind, subType: KotlinType, superType: KotlinType, position: ConstraintPosition) { initialConstraints.add(Constraint(constraintKind, subType, superType, position)) } @@ -375,9 +372,7 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder { } override fun build(): ConstraintSystem { - return ConstraintSystemImpl( - allTypeParameterBounds, usedInBounds, errors, initialConstraints, descriptorToVariable, variableToDescriptor - ) + return ConstraintSystemImpl(allTypeParameterBounds, usedInBounds, errors, initialConstraints, descriptorToVariable) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt index 014ecc823c3..715d61d4339 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt @@ -38,8 +38,7 @@ internal class ConstraintSystemImpl( private val usedInBounds: Map>, private val errors: List, private val initialConstraints: List, - private val descriptorToVariable: Map, - private val variableToDescriptor: Map + private val descriptorToVariable: Map ) : ConstraintSystem { private val localTypeParameterBounds: Map get() = allTypeParameterBounds.filterNot { it.key.isExternal } @@ -88,7 +87,7 @@ internal class ConstraintSystemImpl( val substitutionContext = HashMap() for ((variable, typeBounds) in typeParameterBounds) { val value = typeBounds.value - val typeParameter = if (substituteOriginal) variableToDescriptor[variable]!! else variable.freshTypeParameter + val typeParameter = if (substituteOriginal) variable.originalTypeParameter else variable.freshTypeParameter val type = if (value != null && !TypeUtils.containsSpecialType(value, DONT_CARE)) value else getDefaultType(typeParameter) @@ -110,14 +109,11 @@ internal class ConstraintSystemImpl( get() = descriptorToVariable.keys override val typeVariables: Set - get() = variableToDescriptor.keys + get() = allTypeParameterBounds.keys override fun descriptorToVariable(descriptor: TypeParameterDescriptor): TypeVariable = descriptorToVariable[descriptor] ?: throw IllegalArgumentException("Unknown descriptor: $descriptor") - override fun variableToDescriptor(typeVariable: TypeVariable): TypeParameterDescriptor = - variableToDescriptor[typeVariable] ?: throw IllegalArgumentException("Unknown type variable: $typeVariable") - override fun getTypeBounds(typeVariable: TypeVariable): TypeBoundsImpl { return allTypeParameterBounds[typeVariable] ?: throw IllegalArgumentException("TypeParameterDescriptor is not a type variable for constraint system: $typeVariable") @@ -171,7 +167,6 @@ internal class ConstraintSystemImpl( result.initialConstraints.addAll(initialConstraints.filter { filterConstraintPosition(it.position) }) result.descriptorToVariable.putAll(descriptorToVariable) - result.variableToDescriptor.putAll(variableToDescriptor) return result } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintsUtil.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintsUtil.java index ae6b9a03617..14c0c710c6d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintsUtil.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintsUtil.java @@ -44,7 +44,7 @@ public class ConstraintsUtil { public static Collection getSubstitutorsForConflictingParameters(@NotNull ConstraintSystem constraintSystem) { TypeVariable firstConflictingVariable = getFirstConflictingVariable(constraintSystem); if (firstConflictingVariable == null) return Collections.emptyList(); - TypeParameterDescriptor firstConflictingParameter = constraintSystem.variableToDescriptor(firstConflictingVariable); + TypeParameterDescriptor firstConflictingParameter = firstConflictingVariable.getOriginalTypeParameter(); Collection conflictingTypes = constraintSystem.getTypeBounds(firstConflictingVariable).getValues(); @@ -61,7 +61,7 @@ public class ConstraintsUtil { KotlinType safeType = getSafeValue(constraintSystem, typeVariable); for (Map context : substitutionContexts) { TypeProjection typeProjection = new TypeProjectionImpl(safeType); - context.put(constraintSystem.variableToDescriptor(typeVariable).getTypeConstructor(), typeProjection); + context.put(typeVariable.getOriginalTypeParameter().getTypeConstructor(), typeProjection); } } Collection typeSubstitutors = new ArrayList(substitutionContexts.size()); @@ -78,7 +78,7 @@ public class ConstraintsUtil { return type; } //todo may be error type - return TypeIntersector.getUpperBoundsAsType(constraintSystem.variableToDescriptor(typeVariable)); + return TypeIntersector.getUpperBoundsAsType(typeVariable.getOriginalTypeParameter()); } public static boolean checkUpperBoundIsSatisfied( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/TypeVariable.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/TypeVariable.kt index 040595844c1..c302a0f945f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/TypeVariable.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/TypeVariable.kt @@ -24,11 +24,15 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinTypeImpl -class TypeVariable(val freshTypeParameter: TypeParameterDescriptor, val isExternal: Boolean) { - val name: Name get() = freshTypeParameter.name +class TypeVariable( + val freshTypeParameter: TypeParameterDescriptor, + val originalTypeParameter: TypeParameterDescriptor, + val isExternal: Boolean +) { + val name: Name get() = originalTypeParameter.name val type: KotlinType get() = freshTypeParameter.defaultType fun hasOnlyInputTypesAnnotation(): Boolean = - freshTypeParameter.hasOnlyInputTypesAnnotation() + originalTypeParameter.hasOnlyInputTypesAnnotation() }