Moved 'initial' (renamed from 'topLevel') flag to ConstraintContext
This commit is contained in:
+2
-2
@@ -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()
|
||||||
|
|||||||
+12
-18
@@ -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)
|
||||||
|
|||||||
+5
-4
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user