Reduce number of constraints simplifications

assuming that MutableVariableWithConstraints is constructed either
with no initial constraints or already from simplified list
This commit is contained in:
Ilya Chernikov
2020-03-09 12:15:42 +01:00
parent 84a0e39956
commit c2b866fe7a
2 changed files with 25 additions and 13 deletions
@@ -18,14 +18,19 @@ import kotlin.collections.ArrayList
import kotlin.collections.LinkedHashMap import kotlin.collections.LinkedHashMap
class MutableVariableWithConstraints( class MutableVariableWithConstraints private constructor(
override val typeVariable: TypeVariableMarker, override val typeVariable: TypeVariableMarker,
constraints: Collection<Constraint> = emptyList() constraints: List<Constraint>? // assume simplified and deduplicated
) : VariableWithConstraints { ) : VariableWithConstraints {
constructor(typeVariable: TypeVariableMarker) : this(typeVariable, null)
constructor(other: VariableWithConstraints) : this(other.typeVariable, other.constraints)
override val constraints: List<Constraint> override val constraints: List<Constraint>
get() { get() {
if (simplifiedConstraints == null) { if (simplifiedConstraints == null) {
simplifiedConstraints = simplifyConstraints() simplifiedConstraints = mutableConstraints.simplifyConstraints()
} }
return simplifiedConstraints!! return simplifiedConstraints!!
} }
@@ -36,9 +41,9 @@ class MutableVariableWithConstraints(
.filter { it.position.from is OnlyInputTypeConstraintPosition || it.inputTypePositionBeforeIncorporation != null } .filter { it.position.from is OnlyInputTypeConstraintPosition || it.inputTypePositionBeforeIncorporation != null }
.map { (it.type as KotlinType).unCapture().unwrap() } .map { (it.type as KotlinType).unCapture().unwrap() }
private val mutableConstraints = ArrayList(constraints) private val mutableConstraints = if (constraints == null) ArrayList() else ArrayList(constraints)
private var simplifiedConstraints: List<Constraint>? = null private var simplifiedConstraints: List<Constraint>? = mutableConstraints
// return new actual constraint, if this constraint is new // return new actual constraint, if this constraint is new
fun addConstraint(constraint: Constraint): Constraint? { fun addConstraint(constraint: Constraint): Constraint? {
@@ -80,13 +85,17 @@ class MutableVariableWithConstraints(
// shouldRemove should give true only for tail elements // shouldRemove should give true only for tail elements
internal fun removeLastConstraints(shouldRemove: (Constraint) -> Boolean) { internal fun removeLastConstraints(shouldRemove: (Constraint) -> Boolean) {
mutableConstraints.trimToSize(mutableConstraints.indexOfLast { !shouldRemove(it) } + 1) mutableConstraints.trimToSize(mutableConstraints.indexOfLast { !shouldRemove(it) } + 1)
simplifiedConstraints = null if (simplifiedConstraints !== mutableConstraints) {
simplifiedConstraints = null
}
} }
// This method should be used only when constraint system has state COMPLETION // This method should be used only when constraint system has state COMPLETION
internal fun removeConstrains(shouldRemove: (Constraint) -> Boolean) { internal fun removeConstrains(shouldRemove: (Constraint) -> Boolean) {
mutableConstraints.removeAll(shouldRemove) mutableConstraints.removeAll(shouldRemove)
simplifiedConstraints = null if (simplifiedConstraints !== mutableConstraints) {
simplifiedConstraints = null
}
} }
private fun newConstraintIsUseless(old: Constraint, new: Constraint): Boolean { private fun newConstraintIsUseless(old: Constraint, new: Constraint): Boolean {
@@ -102,11 +111,14 @@ class MutableVariableWithConstraints(
} }
} }
private fun simplifyConstraints(): List<Constraint> { private fun List<Constraint>.simplifyConstraints(): List<Constraint> {
val equalityConstraints = mutableConstraints val equalityConstraints =
.filter { it.kind == ConstraintKind.EQUALITY } filter { it.kind == ConstraintKind.EQUALITY }
.groupBy { it.typeHashCode } .groupBy { it.typeHashCode }
return mutableConstraints.filter { isUsefulConstraint(it, equalityConstraints) } return when {
equalityConstraints.isEmpty() -> this
else -> filter { isUsefulConstraint(it, equalityConstraints) }
}
} }
private fun isUsefulConstraint(constraint: Constraint, equalityConstraints: Map<Int, List<Constraint>>): Boolean { private fun isUsefulConstraint(constraint: Constraint, equalityConstraints: Map<Int, List<Constraint>>): Boolean {
@@ -201,7 +201,7 @@ class NewConstraintSystemImpl(
notProperTypesCache.clear() notProperTypesCache.clear()
} }
for ((variable, constraints) in otherSystem.notFixedTypeVariables) { for ((variable, constraints) in otherSystem.notFixedTypeVariables) {
notFixedTypeVariables[variable] = MutableVariableWithConstraints(constraints.typeVariable, constraints.constraints) notFixedTypeVariables[variable] = MutableVariableWithConstraints(constraints)
} }
storage.initialConstraints.addAll(otherSystem.initialConstraints) storage.initialConstraints.addAll(otherSystem.initialConstraints)
storage.maxTypeDepthFromInitialConstraints = storage.maxTypeDepthFromInitialConstraints =