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
class MutableVariableWithConstraints(
class MutableVariableWithConstraints private constructor(
override val typeVariable: TypeVariableMarker,
constraints: Collection<Constraint> = emptyList()
constraints: List<Constraint>? // assume simplified and deduplicated
) : VariableWithConstraints {
constructor(typeVariable: TypeVariableMarker) : this(typeVariable, null)
constructor(other: VariableWithConstraints) : this(other.typeVariable, other.constraints)
override val constraints: List<Constraint>
get() {
if (simplifiedConstraints == null) {
simplifiedConstraints = simplifyConstraints()
simplifiedConstraints = mutableConstraints.simplifyConstraints()
}
return simplifiedConstraints!!
}
@@ -36,9 +41,9 @@ class MutableVariableWithConstraints(
.filter { it.position.from is OnlyInputTypeConstraintPosition || it.inputTypePositionBeforeIncorporation != null }
.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
fun addConstraint(constraint: Constraint): Constraint? {
@@ -80,13 +85,17 @@ class MutableVariableWithConstraints(
// shouldRemove should give true only for tail elements
internal fun removeLastConstraints(shouldRemove: (Constraint) -> Boolean) {
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
internal fun removeConstrains(shouldRemove: (Constraint) -> Boolean) {
mutableConstraints.removeAll(shouldRemove)
simplifiedConstraints = null
if (simplifiedConstraints !== mutableConstraints) {
simplifiedConstraints = null
}
}
private fun newConstraintIsUseless(old: Constraint, new: Constraint): Boolean {
@@ -102,11 +111,14 @@ class MutableVariableWithConstraints(
}
}
private fun simplifyConstraints(): List<Constraint> {
val equalityConstraints = mutableConstraints
.filter { it.kind == ConstraintKind.EQUALITY }
.groupBy { it.typeHashCode }
return mutableConstraints.filter { isUsefulConstraint(it, equalityConstraints) }
private fun List<Constraint>.simplifyConstraints(): List<Constraint> {
val equalityConstraints =
filter { it.kind == ConstraintKind.EQUALITY }
.groupBy { it.typeHashCode }
return when {
equalityConstraints.isEmpty() -> this
else -> filter { isUsefulConstraint(it, equalityConstraints) }
}
}
private fun isUsefulConstraint(constraint: Constraint, equalityConstraints: Map<Int, List<Constraint>>): Boolean {
@@ -201,7 +201,7 @@ class NewConstraintSystemImpl(
notProperTypesCache.clear()
}
for ((variable, constraints) in otherSystem.notFixedTypeVariables) {
notFixedTypeVariables[variable] = MutableVariableWithConstraints(constraints.typeVariable, constraints.constraints)
notFixedTypeVariables[variable] = MutableVariableWithConstraints(constraints)
}
storage.initialConstraints.addAll(otherSystem.initialConstraints)
storage.maxTypeDepthFromInitialConstraints =