[NI] Refactor OnlyInputType annotation check

Hold position consumed during incorporation in Constraint instead of ConstraintPosition.
This commit is contained in:
Pavel Kirpichenkov
2020-01-15 17:41:44 +03:00
parent 0d393e3fd7
commit fd1305c369
5 changed files with 10 additions and 21 deletions
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.model.*
import org.jetbrains.kotlin.utils.SmartSet
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.util.*
// todo problem: intersection types in constrains: A <: Number, B <: Inv<A & Any> =>? B <: Inv<out Number & Any>
@@ -172,8 +173,7 @@ class ConstraintIncorporator(
val kind = if (isSubtype) ConstraintKind.LOWER else ConstraintKind.UPPER
val inputTypePosition = if (baseConstraint.position.from is OnlyInputTypeConstraintPosition)
baseConstraint.position else null
val inputTypePosition = baseConstraint.position.from.safeAs<OnlyInputTypeConstraintPosition>()
val isNullabilityConstraint = isUsefulForNullabilityConstraint && newConstraint.isNullableNothing()
val constraintContext = ConstraintContext(kind, derivedFrom, inputTypePosition, isNullabilityConstraint)
@@ -70,7 +70,7 @@ class ConstraintInjector(
incorporatePosition: IncorporationConstraintPosition
) {
val possibleNewConstraints = Stack<Pair<TypeVariableMarker, Constraint>>()
val typeCheckerContext = TypeCheckerContext(c, incorporatePosition, lowerType, upperType, possibleNewConstraints, mutableSetOf())
val typeCheckerContext = TypeCheckerContext(c, incorporatePosition, lowerType, upperType, possibleNewConstraints)
typeCheckerContext.runIsSubtypeOf(lowerType, upperType)
while (possibleNewConstraints.isNotEmpty()) {
@@ -85,8 +85,6 @@ class ConstraintInjector(
constraintIncorporator.incorporate(typeCheckerContext, typeVariable, it)
}
}
incorporatePosition.inputTypePositions = typeCheckerContext.preservedInputTypePositions
}
private fun updateAllowedTypeDepth(c: Context, initialType: KotlinTypeMarker) = with(c) {
@@ -122,8 +120,7 @@ class ConstraintInjector(
val position: IncorporationConstraintPosition,
val baseLowerType: KotlinTypeMarker,
val baseUpperType: KotlinTypeMarker,
val possibleNewConstraints: MutableList<Pair<TypeVariableMarker, Constraint>>,
val preservedInputTypePositions: MutableSet<ConstraintPosition>
val possibleNewConstraints: MutableList<Pair<TypeVariableMarker, Constraint>>
) : AbstractTypeCheckerContextForConstraintSystem(), ConstraintIncorporator.Context, TypeSystemInferenceExtensionContext by c {
val baseContext: AbstractTypeCheckerContext = newBaseTypeCheckerContext(isErrorTypeEqualsToAnything, isStubTypeEqualsToAnything)
@@ -234,10 +231,10 @@ class ConstraintInjector(
val newConstraint = Constraint(
kind, targetType, position,
derivedFrom = derivedFrom,
isNullabilityConstraint = isNullabilityConstraint
isNullabilityConstraint = isNullabilityConstraint,
inputTypePositionBeforeIncorporation = inputTypePosition
)
possibleNewConstraints.add(typeVariable to newConstraint)
inputTypePosition?.let { preservedInputTypePositions.add(it) }
}
override val allTypeVariablesWithConstraints: Collection<VariableWithConstraints>
@@ -269,6 +266,6 @@ class ConstraintInjector(
data class ConstraintContext(
val kind: ConstraintKind,
val derivedFrom: Set<TypeVariableMarker>,
val inputTypePosition: ConstraintPosition? = null,
val inputTypePositionBeforeIncorporation: OnlyInputTypeConstraintPosition? = null,
val isNullabilityConstraint: Boolean
)
@@ -86,8 +86,6 @@ class IncorporationConstraintPosition(
val from: ConstraintPosition,
val initialConstraint: InitialConstraint
) : ConstraintPosition() {
lateinit var inputTypePositions: Set<ConstraintPosition>
override fun toString() =
"Incorporate $initialConstraint from position $from"
}
@@ -69,7 +69,8 @@ class Constraint(
val position: IncorporationConstraintPosition,
val typeHashCode: Int = type.hashCode(),
val derivedFrom: Set<TypeVariableMarker>,
val isNullabilityConstraint: Boolean
val isNullabilityConstraint: Boolean,
val inputTypePositionBeforeIncorporation: OnlyInputTypeConstraintPosition? = null
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
@@ -33,16 +33,9 @@ class MutableVariableWithConstraints(
// see @OnlyInputTypes annotation
val projectedInputCallTypes: Collection<UnwrappedType>
get() = mutableConstraints
.filter { it.position.isInputTypePosition }
.filter { it.position.from is OnlyInputTypeConstraintPosition || it.inputTypePositionBeforeIncorporation != null }
.map { (it.type as KotlinType).unCapture().unwrap() }
private val ConstraintPosition?.isInputTypePosition: Boolean
get() = when (this) {
is OnlyInputTypeConstraintPosition -> true
!is IncorporationConstraintPosition -> false
else -> from.isInputTypePosition || inputTypePositions.any { it.isInputTypePosition }
}
private val mutableConstraints = ArrayList(constraints)
private var simplifiedConstraints: List<Constraint>? = null