Moved 'initial' (renamed from 'topLevel') flag to ConstraintContext

This commit is contained in:
Svetlana Isakova
2015-09-02 18:23:03 +03:00
parent 4f28a0a9a1
commit 0999d8ea8e
3 changed files with 19 additions and 24 deletions
@@ -93,12 +93,12 @@ abstract public class AbstractConstraintSystemTest() : JetLiteFixture() {
for (constraint in constraints) { for (constraint in constraints) {
val firstType = testDeclarations.getType(constraint.firstType).assertNotError() val firstType = testDeclarations.getType(constraint.firstType).assertNotError()
val secondType = testDeclarations.getType(constraint.secondType).assertNotError() val secondType = testDeclarations.getType(constraint.secondType).assertNotError()
val context = ConstraintContext(SPECIAL.position()) val context = ConstraintContext(SPECIAL.position(), initial = true)
when (constraint.kind) { when (constraint.kind) {
MyConstraintKind.SUBTYPE -> constraintSystem.addSubtypeConstraint(firstType, secondType, context.position) MyConstraintKind.SUBTYPE -> constraintSystem.addSubtypeConstraint(firstType, secondType, context.position)
MyConstraintKind.SUPERTYPE -> constraintSystem.addSupertypeConstraint(firstType, secondType, context.position) MyConstraintKind.SUPERTYPE -> constraintSystem.addSupertypeConstraint(firstType, secondType, context.position)
MyConstraintKind.EQUAL -> constraintSystem.addConstraint( MyConstraintKind.EQUAL -> constraintSystem.addConstraint(
ConstraintSystemImpl.ConstraintKind.EQUAL, firstType, secondType, context, topLevel = true) ConstraintSystemImpl.ConstraintKind.EQUAL, firstType, secondType, context)
} }
} }
if (fixVariables) constraintSystem.fixVariables() if (fixVariables) constraintSystem.fixVariables()
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.Bound
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.EXACT_BOUND import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.EXACT_BOUND
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.LOWER_BOUND import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.LOWER_BOUND
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.UPPER_BOUND import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.UPPER_BOUND
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.CompoundConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.TYPE_BOUND_POSITION import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.TYPE_BOUND_POSITION
@@ -39,10 +38,7 @@ import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedureCallbacks import org.jetbrains.kotlin.types.checker.TypeCheckingProcedureCallbacks
import org.jetbrains.kotlin.types.typeUtil.getNestedArguments import org.jetbrains.kotlin.types.typeUtil.getNestedArguments
import org.jetbrains.kotlin.types.typeUtil.isDefaultBound import org.jetbrains.kotlin.types.typeUtil.isDefaultBound
import java.util.ArrayList import java.util.*
import java.util.HashMap
import java.util.HashSet
import java.util.LinkedHashMap
public class ConstraintSystemImpl : ConstraintSystem { public class ConstraintSystemImpl : ConstraintSystem {
@@ -204,31 +200,30 @@ public class ConstraintSystemImpl : ConstraintSystem {
if (constrainingType != null && TypeUtils.noExpectedType(constrainingType)) return if (constrainingType != null && TypeUtils.noExpectedType(constrainingType)) return
val newSubjectType = originalToVariablesSubstitutor.substitute(subjectType, Variance.INVARIANT) val newSubjectType = originalToVariablesSubstitutor.substitute(subjectType, Variance.INVARIANT)
addConstraint(SUB_TYPE, newSubjectType, constrainingType, ConstraintContext(constraintPosition), topLevel = true) addConstraint(SUB_TYPE, newSubjectType, constrainingType, ConstraintContext(constraintPosition, initial = true))
} }
override fun addSubtypeConstraint(constrainingType: JetType?, subjectType: JetType, constraintPosition: ConstraintPosition) { override fun addSubtypeConstraint(constrainingType: JetType?, subjectType: JetType, constraintPosition: ConstraintPosition) {
val newSubjectType = originalToVariablesSubstitutor.substitute(subjectType, Variance.INVARIANT) val newSubjectType = originalToVariablesSubstitutor.substitute(subjectType, Variance.INVARIANT)
addConstraint(SUB_TYPE, constrainingType, newSubjectType, ConstraintContext(constraintPosition), topLevel = true) addConstraint(SUB_TYPE, constrainingType, newSubjectType, ConstraintContext(constraintPosition, initial = true))
} }
fun addConstraint( fun addConstraint(
constraintKind: ConstraintKind, constraintKind: ConstraintKind,
subType: JetType?, subType: JetType?,
superType: JetType?, superType: JetType?,
constraintContext: ConstraintContext, constraintContext: ConstraintContext
topLevel: Boolean
) { ) {
val constraintPosition = constraintContext.position val constraintPosition = constraintContext.position
// when processing nested constraints, `derivedFrom` information should be reset // when processing nested constraints, `derivedFrom` information should be reset
val newConstraintContext = ConstraintContext(constraintContext.position, derivedFrom = null) val newConstraintContext = ConstraintContext(constraintContext.position, derivedFrom = null, initial = false)
val typeCheckingProcedure = TypeCheckingProcedure(object : TypeCheckingProcedureCallbacks { val typeCheckingProcedure = TypeCheckingProcedure(object : TypeCheckingProcedureCallbacks {
private var depth = 0 private var depth = 0
override fun assertEqualTypes(a: JetType, b: JetType, typeCheckingProcedure: TypeCheckingProcedure): Boolean { override fun assertEqualTypes(a: JetType, b: JetType, typeCheckingProcedure: TypeCheckingProcedure): Boolean {
depth++ depth++
doAddConstraint(EQUAL, a, b, newConstraintContext, typeCheckingProcedure, topLevel = false) doAddConstraint(EQUAL, a, b, newConstraintContext, typeCheckingProcedure)
depth-- depth--
return true return true
@@ -240,7 +235,7 @@ public class ConstraintSystemImpl : ConstraintSystem {
override fun assertSubtype(subtype: JetType, supertype: JetType, typeCheckingProcedure: TypeCheckingProcedure): Boolean { override fun assertSubtype(subtype: JetType, supertype: JetType, typeCheckingProcedure: TypeCheckingProcedure): Boolean {
depth++ depth++
doAddConstraint(SUB_TYPE, subtype, supertype, newConstraintContext, typeCheckingProcedure, topLevel = false) doAddConstraint(SUB_TYPE, subtype, supertype, newConstraintContext, typeCheckingProcedure)
depth-- depth--
return true return true
} }
@@ -264,7 +259,7 @@ public class ConstraintSystemImpl : ConstraintSystem {
return true return true
} }
}) })
doAddConstraint(constraintKind, subType, superType, constraintContext, typeCheckingProcedure, topLevel) doAddConstraint(constraintKind, subType, superType, constraintContext, typeCheckingProcedure)
} }
private fun isErrorOrSpecialType(type: JetType?, constraintPosition: ConstraintPosition): Boolean { private fun isErrorOrSpecialType(type: JetType?, constraintPosition: ConstraintPosition): Boolean {
@@ -284,8 +279,7 @@ public class ConstraintSystemImpl : ConstraintSystem {
subType: JetType?, subType: JetType?,
superType: JetType?, superType: JetType?,
constraintContext: ConstraintContext, constraintContext: ConstraintContext,
typeCheckingProcedure: TypeCheckingProcedure, typeCheckingProcedure: TypeCheckingProcedure
topLevel: Boolean
) { ) {
val constraintPosition = constraintContext.position val constraintPosition = constraintContext.position
if (isErrorOrSpecialType(subType, constraintPosition) || isErrorOrSpecialType(superType, constraintPosition)) return if (isErrorOrSpecialType(subType, constraintPosition) || isErrorOrSpecialType(superType, constraintPosition)) return
@@ -320,8 +314,8 @@ public class ConstraintSystemImpl : ConstraintSystem {
} }
// if subType is nullable and superType is not nullable, unsafe call or type mismatch error will be generated later, // if subType is nullable and superType is not nullable, unsafe call or type mismatch error will be generated later,
// but constraint system should be solved anyway // but constraint system should be solved anyway
val subTypeNotNullable = if (topLevel) TypeUtils.makeNotNullable(subType) else subType val subTypeNotNullable = if (constraintContext.initial) TypeUtils.makeNotNullable(subType) else subType
val superTypeNotNullable = if (topLevel) TypeUtils.makeNotNullable(superType) else superType val superTypeNotNullable = if (constraintContext.initial) TypeUtils.makeNotNullable(superType) else superType
val result = if (constraintKind == EQUAL) { val result = if (constraintKind == EQUAL) {
typeCheckingProcedure.equalTypes(subTypeNotNullable, superTypeNotNullable) typeCheckingProcedure.equalTypes(subTypeNotNullable, superTypeNotNullable)
} }
@@ -330,7 +324,7 @@ public class ConstraintSystemImpl : ConstraintSystem {
} }
if (!result) errors.add(newTypeInferenceOrParameterConstraintError(constraintPosition)) if (!result) errors.add(newTypeInferenceOrParameterConstraintError(constraintPosition))
} }
if (topLevel) { if (constraintContext.initial) {
storeInitialConstraint(constraintKind, subType, superType, constraintPosition) storeInitialConstraint(constraintKind, subType, superType, constraintPosition)
} }
simplifyConstraint(newSubType, superType) simplifyConstraint(newSubType, superType)
@@ -35,7 +35,8 @@ import java.util.*
data class ConstraintContext( data class ConstraintContext(
val position: ConstraintPosition, val position: ConstraintPosition,
// see TypeBounds.Bound.derivedFrom // see TypeBounds.Bound.derivedFrom
val derivedFrom: Set<TypeParameterDescriptor>? = null) val derivedFrom: Set<TypeParameterDescriptor>? = null,
val initial: Boolean = false)
fun ConstraintSystemImpl.incorporateBound(newBound: Bound) { fun ConstraintSystemImpl.incorporateBound(newBound: Bound) {
val typeVariable = newBound.typeVariable val typeVariable = newBound.typeVariable
@@ -72,9 +73,9 @@ private fun ConstraintSystemImpl.addConstraintFromBounds(old: Bound, new: Bound)
val context = ConstraintContext(CompoundConstraintPosition(old.position, new.position), old.derivedFrom + new.derivedFrom) val context = ConstraintContext(CompoundConstraintPosition(old.position, new.position), old.derivedFrom + new.derivedFrom)
when { when {
old.kind.ordinal() < new.kind.ordinal() -> addConstraint(SUB_TYPE, oldType, newType, context, topLevel = false) old.kind.ordinal() < new.kind.ordinal() -> addConstraint(SUB_TYPE, oldType, newType, context)
old.kind.ordinal() > new.kind.ordinal() -> addConstraint(SUB_TYPE, newType, oldType, context, topLevel = false) old.kind.ordinal() > new.kind.ordinal() -> addConstraint(SUB_TYPE, newType, oldType, context)
old.kind == new.kind && old.kind == EXACT_BOUND -> addConstraint(EQUAL, oldType, newType, context, topLevel = false) old.kind == new.kind && old.kind == EXACT_BOUND -> addConstraint(EQUAL, oldType, newType, context)
} }
} }