Skip to content

Commit

Permalink
Rework checking constraints by presented OnlyInputTypes annotation …
Browse files Browse the repository at this point in the history
…in accordance with changed incorporation mechanism
  • Loading branch information
petukhovv committed Nov 25, 2020
1 parent 0857b9c commit 04846ca
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 20 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class NewConstraintSystemImpl(
{
private val utilContext = constraintInjector.constraintIncorporator.utilContext

private val postponedComputationsAfterAllVariablesAreFixed = mutableListOf<() -> Unit>()

private val storage = MutableConstraintStorage()
private var state = State.BUILDING
private val typeVariablesTransaction: MutableList<TypeVariableMarker> = SmartList()
Expand Down Expand Up @@ -321,42 +323,65 @@ class NewConstraintSystemImpl(
}

// KotlinConstraintSystemCompleter.Context
// TODO: simplify this: do only substitution a fixing type variable rather than running of subtyping and full incorporation
override fun fixVariable(variable: TypeVariableMarker, resultType: KotlinTypeMarker, position: FixVariableConstraintPosition<*>) {
override fun fixVariable(
variable: TypeVariableMarker,
resultType: KotlinTypeMarker,
position: FixVariableConstraintPosition<*>
) = with(utilContext) {
checkState(State.BUILDING, State.COMPLETION)

constraintInjector.addInitialEqualityConstraint(
this, variable.defaultType(), resultType, position
)
constraintInjector.addInitialEqualityConstraint(this@NewConstraintSystemImpl, variable.defaultType(), resultType, position)

val freshTypeConstructor = variable.freshTypeConstructor()

val variableWithConstraints = notFixedTypeVariables.remove(freshTypeConstructor)
checkOnlyInputTypesAnnotation(variableWithConstraints, resultType)

for (variableWithConstraint in notFixedTypeVariables.values) {
variableWithConstraint.removeConstrains {
it.type.contains { it.typeConstructor() == freshTypeConstructor }
for (otherVariableWithConstraints in notFixedTypeVariables.values) {
otherVariableWithConstraints.removeConstrains { otherConstraint ->
otherConstraint.type.contains { it.typeConstructor() == freshTypeConstructor }
}
}

storage.fixedTypeVariables[freshTypeConstructor] = resultType

postponeOnlyInputTypesCheck(variableWithConstraints, resultType)

doPostponedComputationsIfAllVariablesAreFixed()
}

private fun checkOnlyInputTypesAnnotation(
private fun ConstraintSystemUtilContext.postponeOnlyInputTypesCheck(
variableWithConstraints: MutableVariableWithConstraints?,
resultType: KotlinTypeMarker
) {
if (variableWithConstraints == null) return
val variableHasOnlyInputTypes = with(utilContext) { variableWithConstraints.typeVariable.hasOnlyInputTypesAttribute() }
if (!variableHasOnlyInputTypes) return

val resultTypeIsInputType = variableWithConstraints.getProjectedInputCallTypes(utilContext).any { inputType ->
if (AbstractTypeChecker.equalTypes(this, resultType, inputType)) return@any true
val constructor = inputType.typeConstructor()
constructor.isIntersection() && constructor.supertypes().any { AbstractTypeChecker.equalTypes(this, resultType, it) }
if (variableWithConstraints != null && variableWithConstraints.typeVariable.hasOnlyInputTypesAttribute()) {
postponedComputationsAfterAllVariablesAreFixed.add { checkOnlyInputTypesAnnotation(variableWithConstraints, resultType) }
}
}

private fun doPostponedComputationsIfAllVariablesAreFixed() {
if (notFixedTypeVariables.isEmpty()) {
postponedComputationsAfterAllVariablesAreFixed.forEach { it() }
}
}

private fun KotlinTypeMarker.substituteIfNecessary(substitutor: TypeSubstitutorMarker): KotlinTypeMarker {
val doesInputTypeContainsOtherVariables = this.contains { it.typeConstructor() is TypeVariableTypeConstructorMarker }
return if (doesInputTypeContainsOtherVariables) substitutor.safeSubstitute(this) else this
}

private fun checkOnlyInputTypesAnnotation(variableWithConstraints: MutableVariableWithConstraints, resultType: KotlinTypeMarker) {
val substitutor = buildCurrentSubstitutor()
val isResultTypeEqualSomeInputType = variableWithConstraints.getProjectedInputCallTypes(utilContext).any { inputType ->
val inputTypeConstructor = inputType.typeConstructor()

if (inputTypeConstructor.isIntersection()) {
inputTypeConstructor.supertypes().any {
AbstractTypeChecker.equalTypes(this, resultType, it.substituteIfNecessary(substitutor))
}
} else {
AbstractTypeChecker.equalTypes(this, resultType, inputType.substituteIfNecessary(substitutor))
}
}
if (!resultTypeIsInputType) {
if (!isResultTypeEqualSomeInputType) {
addError(OnlyInputTypesDiagnostic(variableWithConstraints.typeVariable))
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME

fun isImportedByDefault(c: String?, x: Set<Int>) = c?.let { it.toInt() } in x

fun box(): String = "OK"

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 04846ca

Please sign in to comment.