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 d0e4a5583ac..4a2076186fe 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 @@ -56,8 +56,8 @@ interface ConstraintSystem { interface Builder { /** - * Registers variables in a constraint system. Returns a substitutor which maps type parameter descriptors given as parameters - * to the corresponding type variables of the system. Use that substitutor to provide constraints to the system + * Registers variables in a constraint system. Returns a substitutor which maps type parameter descriptors passed as parameters + * to the corresponding types of variables of the system. Use that substitutor to provide constraints to the system */ fun registerTypeVariables( call: CallHandle, typeParameters: Collection, external: Boolean = false @@ -79,6 +79,12 @@ interface ConstraintSystem { */ val typeVariableSubstitutors: Map + /** + * Add all variables and constraints from the other system to this one. The other system may not have any common variables + * with this one, or even variables registered for calls, for which this system also has some registered variables + */ + fun add(other: Builder) + fun fixVariables() fun build(): ConstraintSystem 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 61067da9e1d..c8295ad38e1 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 @@ -359,6 +359,30 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder { addBound(typeVariable, value, TypeBounds.BoundKind.EXACT_BOUND, ConstraintContext(ConstraintPositionKind.FROM_COMPLETER.position())) } + override fun add(other: ConstraintSystem.Builder) { + if (other !is ConstraintSystemBuilderImpl) { + throw IllegalArgumentException("Unknown constraint system builder implementation: $other") + } + if (!Collections.disjoint(typeVariableSubstitutors.keys, other.typeVariableSubstitutors.keys)) { + throw IllegalArgumentException( + "Combining two constraint systems only makes sense when they were created for different calls. " + + "Calls of the first system: ${typeVariableSubstitutors.keys}, second: ${other.typeVariableSubstitutors.keys}" + ) + } + if (!Collections.disjoint(other.allTypeParameterBounds.keys, allTypeParameterBounds.keys)) { + throw IllegalArgumentException( + "Combining two constraint systems only makes sense when they have no common variables. " + + "First system variables: ${allTypeParameterBounds.keys}, second: ${other.allTypeParameterBounds.keys}" + ) + } + + allTypeParameterBounds.putAll(other.allTypeParameterBounds) + usedInBounds.putAll(other.usedInBounds) + errors.addAll(other.errors) + initialConstraints.addAll(other.initialConstraints) + typeVariableSubstitutors.putAll(other.typeVariableSubstitutors) + } + override fun fixVariables() { // todo variables should be fixed in the right order val (external, functionTypeParameters) = allTypeParameterBounds.keys.partition { it.isExternal }