Rename AbstractTypeCheckerContext to TypeCheckerState

This commit is contained in:
Dmitriy Novozhilov
2021-08-25 12:45:24 +03:00
parent 28136d7eb0
commit 8b5548df49
37 changed files with 316 additions and 325 deletions
@@ -441,7 +441,7 @@ object FirExpectActualResolver {
if (expectedType == null) return actualType == null if (expectedType == null) return actualType == null
if (actualType == null) return false if (actualType == null) return false
val typeCheckerContext = ConeInferenceContextForExpectActual(expectSession, actualSession).newBaseTypeCheckerContext( val typeCheckerContext = ConeInferenceContextForExpectActual(expectSession, actualSession).newTypeCheckerState(
errorTypesEqualToAnything = false, errorTypesEqualToAnything = false,
stubTypesEqualToAnything = true stubTypesEqualToAnything = true
) )
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.fir.scopes.impl.toConeType
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeTypeCheckerContext import org.jetbrains.kotlin.fir.types.ConeTypeCheckerState
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
@@ -43,7 +43,7 @@ object FirImplementationMismatchChecker : FirClassChecker() {
val classKind = declaration.classKind val classKind = declaration.classKind
if (classKind == ClassKind.ANNOTATION_CLASS || classKind == ClassKind.ENUM_CLASS) return if (classKind == ClassKind.ANNOTATION_CLASS || classKind == ClassKind.ENUM_CLASS) return
val typeCheckerContext = context.session.typeContext.newBaseTypeCheckerContext( val typeCheckerState = context.session.typeContext.newTypeCheckerState(
errorTypesEqualToAnything = false, errorTypesEqualToAnything = false,
stubTypesEqualToAnything = false stubTypesEqualToAnything = false
) )
@@ -52,10 +52,10 @@ object FirImplementationMismatchChecker : FirClassChecker() {
for (name in classScope.getCallableNames()) { for (name in classScope.getCallableNames()) {
classScope.processFunctionsByName(name) { classScope.processFunctionsByName(name) {
checkInheritanceClash(declaration, context, dedupReporter, typeCheckerContext, it, classScope) checkInheritanceClash(declaration, context, dedupReporter, typeCheckerState, it, classScope)
} }
classScope.processPropertiesByName(name) { classScope.processPropertiesByName(name) {
checkInheritanceClash(declaration, context, dedupReporter, typeCheckerContext, it, classScope) checkInheritanceClash(declaration, context, dedupReporter, typeCheckerState, it, classScope)
checkValOverridesVar(declaration, context, dedupReporter, it, classScope) checkValOverridesVar(declaration, context, dedupReporter, it, classScope)
} }
checkConflictingMembers(declaration, context, dedupReporter, classScope, name) checkConflictingMembers(declaration, context, dedupReporter, classScope, name)
@@ -66,7 +66,7 @@ object FirImplementationMismatchChecker : FirClassChecker() {
containingClass: FirClass, containingClass: FirClass,
context: CheckerContext, context: CheckerContext,
reporter: DiagnosticReporter, reporter: DiagnosticReporter,
typeCheckerContext: ConeTypeCheckerContext, typeCheckerState: ConeTypeCheckerState,
symbol: FirCallableSymbol<*>, symbol: FirCallableSymbol<*>,
classScope: FirTypeScope classScope: FirTypeScope
) { ) {
@@ -96,9 +96,9 @@ object FirImplementationMismatchChecker : FirClassChecker() {
): Boolean { ): Boolean {
val inheritedTypeSubstituted = inheritedType.substituteTypeParameters(inheritedMember, baseMember, context) val inheritedTypeSubstituted = inheritedType.substituteTypeParameters(inheritedMember, baseMember, context)
return if (baseMember is FirPropertySymbol && baseMember.isVar) return if (baseMember is FirPropertySymbol && baseMember.isVar)
AbstractTypeChecker.equalTypes(typeCheckerContext, inheritedTypeSubstituted, baseType) AbstractTypeChecker.equalTypes(typeCheckerState, inheritedTypeSubstituted, baseType)
else else
AbstractTypeChecker.isSubtypeOf(typeCheckerContext, inheritedTypeSubstituted, baseType) AbstractTypeChecker.isSubtypeOf(typeCheckerState, inheritedTypeSubstituted, baseType)
} }
val intersectionSymbols = when { val intersectionSymbols = when {
@@ -34,11 +34,11 @@ import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.upperBoundIfFlexible import org.jetbrains.kotlin.fir.types.upperBoundIfFlexible
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.TypeCheckerState
object FirOverrideChecker : FirClassChecker() { object FirOverrideChecker : FirClassChecker() {
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
val typeCheckerContext = context.session.typeContext.newBaseTypeCheckerContext( val typeCheckerState = context.session.typeContext.newTypeCheckerState(
errorTypesEqualToAnything = false, errorTypesEqualToAnything = false,
stubTypesEqualToAnything = false stubTypesEqualToAnything = false
) )
@@ -47,7 +47,7 @@ object FirOverrideChecker : FirClassChecker() {
for (it in declaration.declarations) { for (it in declaration.declarations) {
if (it is FirSimpleFunction || it is FirProperty) { if (it is FirSimpleFunction || it is FirProperty) {
checkMember((it as FirCallableDeclaration).symbol, declaration, reporter, typeCheckerContext, firTypeScope, context) checkMember((it as FirCallableDeclaration).symbol, declaration, reporter, typeCheckerState, firTypeScope, context)
} }
} }
} }
@@ -172,7 +172,7 @@ object FirOverrideChecker : FirClassChecker() {
// See [OverrideResolver#isReturnTypeOkForOverride] // See [OverrideResolver#isReturnTypeOkForOverride]
private fun FirCallableSymbol<*>.checkReturnType( private fun FirCallableSymbol<*>.checkReturnType(
overriddenSymbols: List<FirCallableSymbol<*>>, overriddenSymbols: List<FirCallableSymbol<*>>,
typeCheckerContext: AbstractTypeCheckerContext, typeCheckerState: TypeCheckerState,
context: CheckerContext, context: CheckerContext,
): FirCallableSymbol<*>? { ): FirCallableSymbol<*>? {
val overridingReturnType = resolvedReturnTypeRef.coneType val overridingReturnType = resolvedReturnTypeRef.coneType
@@ -191,9 +191,9 @@ object FirOverrideChecker : FirClassChecker() {
val isReturnTypeOkForOverride = val isReturnTypeOkForOverride =
if (overriddenDeclaration is FirPropertySymbol && overriddenDeclaration.isVar) if (overriddenDeclaration is FirPropertySymbol && overriddenDeclaration.isVar)
AbstractTypeChecker.equalTypes(typeCheckerContext, overridingReturnType, overriddenReturnType) AbstractTypeChecker.equalTypes(typeCheckerState, overridingReturnType, overriddenReturnType)
else else
AbstractTypeChecker.isSubtypeOf(typeCheckerContext, overridingReturnType, overriddenReturnType) AbstractTypeChecker.isSubtypeOf(typeCheckerState, overridingReturnType, overriddenReturnType)
if (!isReturnTypeOkForOverride) { if (!isReturnTypeOkForOverride) {
return overriddenDeclaration return overriddenDeclaration
@@ -207,7 +207,7 @@ object FirOverrideChecker : FirClassChecker() {
member: FirCallableSymbol<*>, member: FirCallableSymbol<*>,
containingClass: FirClass, containingClass: FirClass,
reporter: DiagnosticReporter, reporter: DiagnosticReporter,
typeCheckerContext: AbstractTypeCheckerContext, typeCheckerState: TypeCheckerState,
firTypeScope: FirTypeScope, firTypeScope: FirTypeScope,
context: CheckerContext context: CheckerContext
) { ) {
@@ -268,7 +268,7 @@ object FirOverrideChecker : FirClassChecker() {
val restriction = member.checkReturnType( val restriction = member.checkReturnType(
overriddenSymbols = overriddenMemberSymbols, overriddenSymbols = overriddenMemberSymbols,
typeCheckerContext = typeCheckerContext, typeCheckerState = typeCheckerState,
context = context, context = context,
) ?: return ) ?: return
when (member) { when (member) {
@@ -695,7 +695,7 @@ class CallAndReferenceGenerator(
// If the type of the argument is already an explicitly subtype of the type of the parameter, we don't need SAM conversion. // If the type of the argument is already an explicitly subtype of the type of the parameter, we don't need SAM conversion.
if (argument.typeRef !is FirResolvedTypeRef || if (argument.typeRef !is FirResolvedTypeRef ||
AbstractTypeChecker.isSubtypeOf( AbstractTypeChecker.isSubtypeOf(
session.inferenceComponents.ctx.newBaseTypeCheckerContext( session.inferenceComponents.ctx.newTypeCheckerState(
errorTypesEqualToAnything = false, stubTypesEqualToAnything = true errorTypesEqualToAnything = false, stubTypesEqualToAnything = true
), ),
argument.typeRef.coneType, argument.typeRef.coneType,
@@ -537,7 +537,7 @@ fun FirExpression.isFunctional(
val returnTypeCompatible = val returnTypeCompatible =
expectedReturnType is ConeTypeParameterType || expectedReturnType is ConeTypeParameterType ||
AbstractTypeChecker.isSubtypeOf( AbstractTypeChecker.isSubtypeOf(
session.inferenceComponents.ctx.newBaseTypeCheckerContext( session.inferenceComponents.ctx.newTypeCheckerState(
errorTypesEqualToAnything = false, errorTypesEqualToAnything = false,
stubTypesEqualToAnything = true stubTypesEqualToAnything = true
), ),
@@ -557,7 +557,7 @@ fun FirExpression.isFunctional(
val expectedParameterType = expectedParameter.lowerBoundIfFlexible() val expectedParameterType = expectedParameter.lowerBoundIfFlexible()
expectedParameterType is ConeTypeParameterType || expectedParameterType is ConeTypeParameterType ||
AbstractTypeChecker.isSubtypeOf( AbstractTypeChecker.isSubtypeOf(
session.inferenceComponents.ctx.newBaseTypeCheckerContext( session.inferenceComponents.ctx.newTypeCheckerState(
errorTypesEqualToAnything = false, errorTypesEqualToAnything = false,
stubTypesEqualToAnything = true stubTypesEqualToAnything = true
), ),
@@ -649,7 +649,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
if (originalType !is ConeClassLikeType) return type if (originalType !is ConeClassLikeType) return type
val baseFirClass = originalType.lookupTag.toSymbol(session)?.fir ?: return type val baseFirClass = originalType.lookupTag.toSymbol(session)?.fir ?: return type
val isSubtype = AbstractTypeChecker.isSubtypeOfClass( val isSubtype = AbstractTypeChecker.isSubtypeOfClass(
session.typeContext.newBaseTypeCheckerContext(errorTypesEqualToAnything = false, stubTypesEqualToAnything = true), session.typeContext.newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = true),
originalType.lookupTag, originalType.lookupTag,
type.lookupTag type.lookupTag
) )
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.fir.types.coneTypeSafe
import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
class FirTypeIntersectionScope private constructor( class FirTypeIntersectionScope private constructor(
session: FirSession, session: FirSession,
@@ -35,7 +34,7 @@ class FirTypeIntersectionScope private constructor(
private val absentProperties: MutableSet<Name> = mutableSetOf() private val absentProperties: MutableSet<Name> = mutableSetOf()
private val absentClassifiers: MutableSet<Name> = mutableSetOf() private val absentClassifiers: MutableSet<Name> = mutableSetOf()
private val typeCheckerContext = session.typeContext.newBaseTypeCheckerContext(false, false) private val typeCheckerState = session.typeContext.newTypeCheckerState(false, false)
private val overriddenSymbols: MutableMap<FirCallableSymbol<*>, Collection<MemberWithBaseScope<out FirCallableSymbol<*>>>> = private val overriddenSymbols: MutableMap<FirCallableSymbol<*>, Collection<MemberWithBaseScope<out FirCallableSymbol<*>>>> =
mutableMapOf() mutableMapOf()
@@ -420,7 +419,7 @@ class FirTypeIntersectionScope private constructor(
require(bFir is FirProperty) { "b is " + b.javaClass } require(bFir is FirProperty) { "b is " + b.javaClass }
// TODO: if (!OverridingUtil.isAccessorMoreSpecific(pa.getSetter(), pb.getSetter())) return false // TODO: if (!OverridingUtil.isAccessorMoreSpecific(pa.getSetter(), pb.getSetter())) return false
return if (aFir.isVar && bFir.isVar) { return if (aFir.isVar && bFir.isVar) {
AbstractTypeChecker.equalTypes(typeCheckerContext as AbstractTypeCheckerContext, aReturnType, bReturnType) AbstractTypeChecker.equalTypes(typeCheckerState, aReturnType, bReturnType)
} else { // both vals or var vs val: val can't be more specific then var } else { // both vals or var vs val: val can't be more specific then var
!(!aFir.isVar && bFir.isVar) && isTypeMoreSpecific(aReturnType, bReturnType) !(!aFir.isVar && bFir.isVar) && isTypeMoreSpecific(aReturnType, bReturnType)
} }
@@ -429,7 +428,7 @@ class FirTypeIntersectionScope private constructor(
} }
private fun isTypeMoreSpecific(a: ConeKotlinType, b: ConeKotlinType): Boolean = private fun isTypeMoreSpecific(a: ConeKotlinType, b: ConeKotlinType): Boolean =
AbstractTypeChecker.isSubtypeOf(typeCheckerContext as AbstractTypeCheckerContext, a, b) AbstractTypeChecker.isSubtypeOf(typeCheckerState, a, b)
private fun <D : FirCallableSymbol<*>> findMemberWithMaxVisibility(members: Collection<MemberWithBaseScope<D>>): MemberWithBaseScope<D> { private fun <D : FirCallableSymbol<*>> findMemberWithMaxVisibility(members: Collection<MemberWithBaseScope<D>>): MemberWithBaseScope<D> {
assert(members.isNotEmpty()) assert(members.isNotEmpty())
@@ -106,11 +106,11 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
return ConeStarProjection return ConeStarProjection
} }
override fun newBaseTypeCheckerContext( override fun newTypeCheckerState(
errorTypesEqualToAnything: Boolean, errorTypesEqualToAnything: Boolean,
stubTypesEqualToAnything: Boolean stubTypesEqualToAnything: Boolean
): ConeTypeCheckerContext = ): ConeTypeCheckerState =
ConeTypeCheckerContext(errorTypesEqualToAnything, stubTypesEqualToAnything, this) ConeTypeCheckerState(errorTypesEqualToAnything, stubTypesEqualToAnything, this)
override fun KotlinTypeMarker.canHaveUndefinedNullability(): Boolean { override fun KotlinTypeMarker.canHaveUndefinedNullability(): Boolean {
require(this is ConeKotlinType) require(this is ConeKotlinType)
@@ -198,7 +198,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
override fun Collection<KotlinTypeMarker>.singleBestRepresentative(): KotlinTypeMarker? { override fun Collection<KotlinTypeMarker>.singleBestRepresentative(): KotlinTypeMarker? {
if (this.size == 1) return this.first() if (this.size == 1) return this.first()
val context = newBaseTypeCheckerContext(errorTypesEqualToAnything = true, stubTypesEqualToAnything = true) val context = newTypeCheckerState(errorTypesEqualToAnything = true, stubTypesEqualToAnything = true)
return this.firstOrNull { candidate -> return this.firstOrNull { candidate ->
this.all { other -> this.all { other ->
// We consider error types equal to anything here, so that intersections like // We consider error types equal to anything here, so that intersections like
@@ -6,14 +6,14 @@
package org.jetbrains.kotlin.fir.types package org.jetbrains.kotlin.fir.types
import org.jetbrains.kotlin.types.AbstractNullabilityChecker import org.jetbrains.kotlin.types.AbstractNullabilityChecker
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.TypeCheckerState
object ConeNullabilityChecker { object ConeNullabilityChecker {
fun isSubtypeOfAny(context: ConeTypeContext, type: ConeKotlinType): Boolean { fun isSubtypeOfAny(context: ConeTypeContext, type: ConeKotlinType): Boolean {
val actualType = with(context) { type.lowerBoundIfFlexible() } val actualType = with(context) { type.lowerBoundIfFlexible() }
return with(AbstractNullabilityChecker) { return with(AbstractNullabilityChecker) {
context.newBaseTypeCheckerContext(errorTypesEqualToAnything = false, stubTypesEqualToAnything = true) context.newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = true)
.hasNotNullSupertype(actualType, AbstractTypeCheckerContext.SupertypesPolicy.LowerIfFlexible) .hasNotNullSupertype(actualType, TypeCheckerState.SupertypesPolicy.LowerIfFlexible)
} }
} }
} }
@@ -31,9 +31,9 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext.SupertypesPolicy.DoCustomTransform import org.jetbrains.kotlin.types.TypeCheckerState.SupertypesPolicy.DoCustomTransform
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext.SupertypesPolicy.LowerIfFlexible import org.jetbrains.kotlin.types.TypeCheckerState.SupertypesPolicy.LowerIfFlexible
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.types.model.*
@@ -567,12 +567,12 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
} }
} }
class ConeTypeCheckerContext( class ConeTypeCheckerState(
override val isErrorTypeEqualsToAnything: Boolean, override val isErrorTypeEqualsToAnything: Boolean,
override val isStubTypeEqualsToAnything: Boolean, override val isStubTypeEqualsToAnything: Boolean,
override val typeSystemContext: ConeInferenceContext, override val typeSystemContext: ConeInferenceContext,
val kotlinTypePreparator: ConeTypePreparator = ConeTypePreparator.getDefault(typeSystemContext.session), val kotlinTypePreparator: ConeTypePreparator = ConeTypePreparator.getDefault(typeSystemContext.session),
) : AbstractTypeCheckerContext() { ) : TypeCheckerState() {
val session: FirSession = typeSystemContext.session val session: FirSession = typeSystemContext.session
@@ -595,7 +595,7 @@ class ConeTypeCheckerContext(
ConeSubstitutor.Empty ConeSubstitutor.Empty
} }
return object : DoCustomTransform() { return object : DoCustomTransform() {
override fun transformType(context: AbstractTypeCheckerContext, type: KotlinTypeMarker): SimpleTypeMarker { override fun transformType(state: TypeCheckerState, type: KotlinTypeMarker): SimpleTypeMarker {
val lowerBound = type.lowerBoundIfFlexible() val lowerBound = type.lowerBoundIfFlexible()
require(lowerBound is ConeKotlinType) require(lowerBound is ConeKotlinType)
return substitutor.substituteOrSelf(lowerBound) as SimpleTypeMarker return substitutor.substituteOrSelf(lowerBound) as SimpleTypeMarker
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.model.CaptureStatus import org.jetbrains.kotlin.types.model.CaptureStatus
import org.jetbrains.kotlin.types.model.SimpleTypeMarker import org.jetbrains.kotlin.types.model.SimpleTypeMarker
import org.jetbrains.kotlin.types.model.TypeConstructorMarker import org.jetbrains.kotlin.types.model.TypeConstructorMarker
@@ -29,24 +29,24 @@ class FirCorrespondingSupertypesCache(private val session: FirSession) : FirSess
): List<ConeClassLikeType>? { ): List<ConeClassLikeType>? {
if (type !is ConeClassLikeType || supertypeConstructor !is ConeClassLikeLookupTag) return null if (type !is ConeClassLikeType || supertypeConstructor !is ConeClassLikeLookupTag) return null
val context = session.typeContext.newBaseTypeCheckerContext( val typeCheckerState = session.typeContext.newTypeCheckerState(
errorTypesEqualToAnything = false, errorTypesEqualToAnything = false,
stubTypesEqualToAnything = true stubTypesEqualToAnything = true
) )
val lookupTag = type.lookupTag val lookupTag = type.lookupTag
if (lookupTag == supertypeConstructor) return listOf(captureType(type, context.typeSystemContext)) if (lookupTag == supertypeConstructor) return listOf(captureType(type, typeCheckerState.typeSystemContext))
if (lookupTag !in cache) { if (lookupTag !in cache) {
cache[lookupTag] = computeSupertypesMap(lookupTag, context) cache[lookupTag] = computeSupertypesMap(lookupTag, typeCheckerState)
} }
val resultTypes = cache[lookupTag]?.getOrDefault(supertypeConstructor, emptyList()) ?: return null val resultTypes = cache[lookupTag]?.getOrDefault(supertypeConstructor, emptyList()) ?: return null
if (type.typeArguments.isEmpty()) return resultTypes if (type.typeArguments.isEmpty()) return resultTypes
val capturedType = captureType(type, context.typeSystemContext) val capturedType = captureType(type, typeCheckerState.typeSystemContext)
val substitutionSupertypePolicy = context.substitutionSupertypePolicy(capturedType) val substitutionSupertypePolicy = typeCheckerState.substitutionSupertypePolicy(capturedType)
return resultTypes.map { return resultTypes.map {
substitutionSupertypePolicy.transformType(context, it) as ConeClassLikeType substitutionSupertypePolicy.transformType(typeCheckerState, it) as ConeClassLikeType
} }
} }
@@ -55,7 +55,7 @@ class FirCorrespondingSupertypesCache(private val session: FirSession) : FirSess
private fun computeSupertypesMap( private fun computeSupertypesMap(
subtypeLookupTag: ConeClassLikeLookupTag, subtypeLookupTag: ConeClassLikeLookupTag,
context: ConeTypeCheckerContext state: ConeTypeCheckerState
): Map<ConeClassLikeLookupTag, List<ConeClassLikeType>>? { ): Map<ConeClassLikeLookupTag, List<ConeClassLikeType>>? {
val resultingMap = HashMap<ConeClassLikeLookupTag, List<ConeClassLikeType>>() val resultingMap = HashMap<ConeClassLikeLookupTag, List<ConeClassLikeType>>()
@@ -68,10 +68,10 @@ class FirCorrespondingSupertypesCache(private val session: FirSession) : FirSess
isNullable = false isNullable = false
) )
if (context.anySupertype( if (state.anySupertype(
defaultType, defaultType,
{ it !is ConeClassLikeType || it.lookupTag.toSymbol(session) !is FirClassLikeSymbol<*> } { it !is ConeClassLikeType || it.lookupTag.toSymbol(session) !is FirClassLikeSymbol<*> }
) { supertype -> computeSupertypePolicyAndPutInMap(supertype, resultingMap, context) } ) { supertype -> computeSupertypePolicyAndPutInMap(supertype, resultingMap, state) }
) { ) {
return null return null
} }
@@ -84,20 +84,20 @@ class FirCorrespondingSupertypesCache(private val session: FirSession) : FirSess
private fun computeSupertypePolicyAndPutInMap( private fun computeSupertypePolicyAndPutInMap(
supertype: SimpleTypeMarker, supertype: SimpleTypeMarker,
resultingMap: MutableMap<ConeClassLikeLookupTag, List<ConeClassLikeType>>, resultingMap: MutableMap<ConeClassLikeLookupTag, List<ConeClassLikeType>>,
context: ConeTypeCheckerContext state: ConeTypeCheckerState
): AbstractTypeCheckerContext.SupertypesPolicy { ): TypeCheckerState.SupertypesPolicy {
val supertypeLookupTag = (supertype as ConeClassLikeType).lookupTag val supertypeLookupTag = (supertype as ConeClassLikeType).lookupTag
val captured = val captured =
context.typeSystemContext.captureFromArguments(supertype, CaptureStatus.FOR_SUBTYPING) as ConeClassLikeType? ?: supertype state.typeSystemContext.captureFromArguments(supertype, CaptureStatus.FOR_SUBTYPING) as ConeClassLikeType? ?: supertype
resultingMap[supertypeLookupTag] = listOf(captured) resultingMap[supertypeLookupTag] = listOf(captured)
return when { return when {
with(context.typeSystemContext) { captured.argumentsCount() } == 0 -> { with(state.typeSystemContext) { captured.argumentsCount() } == 0 -> {
AbstractTypeCheckerContext.SupertypesPolicy.LowerIfFlexible TypeCheckerState.SupertypesPolicy.LowerIfFlexible
} }
else -> { else -> {
context.substitutionSupertypePolicy(captured) state.substitutionSupertypePolicy(captured)
} }
} }
} }
@@ -55,7 +55,7 @@ fun ConeDefinitelyNotNullType.Companion.create(
return when { return when {
original is ConeDefinitelyNotNullType -> original original is ConeDefinitelyNotNullType -> original
typeContext typeContext
.newBaseTypeCheckerContext(errorTypesEqualToAnything = false, stubTypesEqualToAnything = false) .newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = false)
.makesSenseToBeDefinitelyNotNull(original, useCorrectedNullabilityForFlexibleTypeParameters) -> .makesSenseToBeDefinitelyNotNull(original, useCorrectedNullabilityForFlexibleTypeParameters) ->
ConeDefinitelyNotNullType( ConeDefinitelyNotNullType(
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.types.AbstractNullabilityChecker import org.jetbrains.kotlin.types.AbstractNullabilityChecker
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.ConstantValueKind import org.jetbrains.kotlin.types.ConstantValueKind
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract import kotlin.contracts.contract
@@ -151,7 +151,7 @@ fun FirTypeProjection.toConeTypeProjection(): ConeTypeProjection =
else -> error("!") else -> error("!")
} }
fun AbstractTypeCheckerContext.makesSenseToBeDefinitelyNotNull( fun TypeCheckerState.makesSenseToBeDefinitelyNotNull(
type: ConeKotlinType, type: ConeKotlinType,
useCorrectedNullabilityForFlexibleTypeParameters: Boolean useCorrectedNullabilityForFlexibleTypeParameters: Boolean
): Boolean { ): Boolean {
@@ -164,7 +164,7 @@ class JavaNullabilityChecker(val upperBoundChecker: UpperBoundChecker) : Additio
var metWrongNullabilityInsideArguments = false var metWrongNullabilityInsideArguments = false
val typeContext: AbstractTypeCheckerContext = object : ClassicTypeCheckerContext(errorTypeEqualsToAnything = true) { val typeState: TypeCheckerState = object : ClassicTypeCheckerState(errorTypeEqualsToAnything = true) {
private var expectsTypeArgument = false private var expectsTypeArgument = false
override fun customIsSubtypeOf(subType: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean { override fun customIsSubtypeOf(subType: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean {
@@ -183,7 +183,7 @@ class JavaNullabilityChecker(val upperBoundChecker: UpperBoundChecker) : Additio
} }
} }
AbstractTypeChecker.isSubtypeOf(typeContext, expressionType, c.expectedType) AbstractTypeChecker.isSubtypeOf(typeState, expressionType, c.expectedType)
return metWrongNullabilityInsideArguments return metWrongNullabilityInsideArguments
} }
@@ -194,7 +194,7 @@ class JavaNullabilityChecker(val upperBoundChecker: UpperBoundChecker) : Additio
): Boolean { ): Boolean {
if (superType !is NotNullTypeVariable) return false if (superType !is NotNullTypeVariable) return false
return !AbstractNullabilityChecker.isSubtypeOfAny( return !AbstractNullabilityChecker.isSubtypeOfAny(
ClassicTypeCheckerContext(errorTypeEqualsToAnything = true) as AbstractTypeCheckerContext, ClassicTypeCheckerState(errorTypeEqualsToAnything = true) as TypeCheckerState,
subType subType
) )
} }
@@ -36,7 +36,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE import org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE
import org.jetbrains.kotlin.types.checker.ClassicTypeCheckerContext import org.jetbrains.kotlin.types.checker.ClassicTypeCheckerState
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
@@ -232,7 +232,7 @@ class BuilderInferenceSupport(
with(NewKotlinTypeChecker.Default) { with(NewKotlinTypeChecker.Default) {
val parameterType = getEffectiveExpectedType(argumentMatch.valueParameter, valueArgument, context) val parameterType = getEffectiveExpectedType(argumentMatch.valueParameter, valueArgument, context)
BuilderInferenceTypeCheckerContext(allowOnlyTrivialConstraints = false).isSubtypeOf(kotlinType.unwrap(), parameterType.unwrap()) BuilderInferenceTypeCheckerState(allowOnlyTrivialConstraints = false).isSubtypeOf(kotlinType.unwrap(), parameterType.unwrap())
} }
} }
@@ -245,16 +245,16 @@ class BuilderInferenceSupport(
resultingCall.extensionReceiver?.let { actualReceiver -> resultingCall.extensionReceiver?.let { actualReceiver ->
with(NewKotlinTypeChecker.Default) { with(NewKotlinTypeChecker.Default) {
BuilderInferenceTypeCheckerContext(allowOnlyTrivialConstraints = allowOnlyTrivialConstraintsForReceiver).isSubtypeOf( BuilderInferenceTypeCheckerState(allowOnlyTrivialConstraints = allowOnlyTrivialConstraintsForReceiver).isSubtypeOf(
actualReceiver.type.unwrap(), extensionReceiver.value.type.unwrap() actualReceiver.type.unwrap(), extensionReceiver.value.type.unwrap()
) )
} }
} }
} }
private class BuilderInferenceTypeCheckerContext( private class BuilderInferenceTypeCheckerState(
private val allowOnlyTrivialConstraints: Boolean private val allowOnlyTrivialConstraints: Boolean
) : ClassicTypeCheckerContext(errorTypeEqualsToAnything = true) { ) : ClassicTypeCheckerState(errorTypeEqualsToAnything = true) {
override fun addSubtypeConstraint(subType: KotlinTypeMarker, superType: KotlinTypeMarker, isFromNullabilityConstraint: Boolean): Boolean? { override fun addSubtypeConstraint(subType: KotlinTypeMarker, superType: KotlinTypeMarker, isFromNullabilityConstraint: Boolean): Boolean? {
require(subType is UnwrappedType) require(subType is UnwrappedType)
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.utils.addToStdlib.cast import org.jetbrains.kotlin.utils.addToStdlib.cast
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
@@ -215,7 +215,7 @@ internal class CollectionStubMethodLowering(val context: JvmBackendContext) : Cl
if (superFun.typeParameters.size != overridingFun.typeParameters.size) return false if (superFun.typeParameters.size != overridingFun.typeParameters.size) return false
if (superFun.valueParameters.size != overridingFun.valueParameters.size) return false if (superFun.valueParameters.size != overridingFun.valueParameters.size) return false
val typeChecker = createTypeChecker(superFun, overridingFun) val typeChecker = createTypeCheckerState(superFun, overridingFun)
// Note that type parameters equivalence check doesn't really happen on collection stubs // Note that type parameters equivalence check doesn't really happen on collection stubs
// (because members of Kotlin built-in collection classes don't have type parameters of their own), // (because members of Kotlin built-in collection classes don't have type parameters of their own),
@@ -228,8 +228,8 @@ internal class CollectionStubMethodLowering(val context: JvmBackendContext) : Cl
return true return true
} }
private fun createTypeChecker(overrideFun: IrSimpleFunction, parentFun: IrSimpleFunction): AbstractTypeCheckerContext = private fun createTypeCheckerState(overrideFun: IrSimpleFunction, parentFun: IrSimpleFunction): TypeCheckerState =
IrTypeCheckerContext( IrTypeCheckerState(
IrTypeSystemContextWithAdditionalAxioms( IrTypeSystemContextWithAdditionalAxioms(
context.typeSystem, context.typeSystem,
overrideFun.typeParameters, overrideFun.typeParameters,
@@ -240,7 +240,7 @@ internal class CollectionStubMethodLowering(val context: JvmBackendContext) : Cl
private fun areTypeParametersEquivalent( private fun areTypeParametersEquivalent(
overrideFun: IrSimpleFunction, overrideFun: IrSimpleFunction,
parentFun: IrSimpleFunction, parentFun: IrSimpleFunction,
typeChecker: AbstractTypeCheckerContext typeChecker: TypeCheckerState
): Boolean = ): Boolean =
overrideFun.typeParameters.zip(parentFun.typeParameters) overrideFun.typeParameters.zip(parentFun.typeParameters)
.all { (typeParameter1, typeParameter2) -> .all { (typeParameter1, typeParameter2) ->
@@ -253,7 +253,7 @@ internal class CollectionStubMethodLowering(val context: JvmBackendContext) : Cl
private fun areValueParametersEquivalent( private fun areValueParametersEquivalent(
overrideFun: IrSimpleFunction, overrideFun: IrSimpleFunction,
parentFun: IrSimpleFunction, parentFun: IrSimpleFunction,
typeChecker: AbstractTypeCheckerContext typeChecker: TypeCheckerState
): Boolean = ): Boolean =
overrideFun.valueParameters.zip(parentFun.valueParameters) overrideFun.valueParameters.zip(parentFun.valueParameters)
.all { (valueParameter1, valueParameter2) -> .all { (valueParameter1, valueParameter2) ->
@@ -263,7 +263,7 @@ internal class CollectionStubMethodLowering(val context: JvmBackendContext) : Cl
internal fun isReturnTypeOverrideCompliant( internal fun isReturnTypeOverrideCompliant(
overrideFun: IrSimpleFunction, overrideFun: IrSimpleFunction,
parentFun: IrSimpleFunction, parentFun: IrSimpleFunction,
typeChecker: AbstractTypeCheckerContext typeChecker: TypeCheckerState
): Boolean = ): Boolean =
AbstractTypeChecker.isSubtypeOf(typeChecker, overrideFun.returnType, parentFun.returnType) AbstractTypeChecker.isSubtypeOf(typeChecker, overrideFun.returnType, parentFun.returnType)
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.DescriptorVisibility import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
@@ -20,7 +19,7 @@ import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.incompatible import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.incompatible
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
abstract class FakeOverrideBuilderStrategy { abstract class FakeOverrideBuilderStrategy {
@@ -439,14 +438,14 @@ class IrOverridingUtil(
return if (a == null || b == null) true else isVisibilityMoreSpecific(a, b) return if (a == null || b == null) true else isVisibilityMoreSpecific(a, b)
} }
private fun IrTypeCheckerContext.isSubtypeOf(a: IrType, b: IrType) = private fun IrTypeCheckerState.isSubtypeOf(a: IrType, b: IrType) =
AbstractTypeChecker.isSubtypeOf(this as AbstractTypeCheckerContext, a, b) AbstractTypeChecker.isSubtypeOf(this as TypeCheckerState, a, b)
private fun IrTypeCheckerContext.equalTypes(a: IrType, b: IrType) = private fun IrTypeCheckerState.equalTypes(a: IrType, b: IrType) =
AbstractTypeChecker.equalTypes(this as AbstractTypeCheckerContext, a, b) AbstractTypeChecker.equalTypes(this as TypeCheckerState, a, b)
private fun createTypeChecker(a: List<IrTypeParameter>, b: List<IrTypeParameter>) = private fun createTypeCheckerState(a: List<IrTypeParameter>, b: List<IrTypeParameter>) =
IrTypeCheckerContext(IrTypeSystemContextWithAdditionalAxioms(typeSystem, a, b)) IrTypeCheckerState(IrTypeSystemContextWithAdditionalAxioms(typeSystem, a, b))
private fun isReturnTypeMoreSpecific( private fun isReturnTypeMoreSpecific(
a: IrOverridableMember, a: IrOverridableMember,
@@ -454,7 +453,7 @@ class IrOverridingUtil(
b: IrOverridableMember, b: IrOverridableMember,
bReturnType: IrType bReturnType: IrType
): Boolean { ): Boolean {
val typeCheckerContext = createTypeChecker(a.typeParameters, b.typeParameters) val typeCheckerContext = createTypeCheckerState(a.typeParameters, b.typeParameters)
return typeCheckerContext.isSubtypeOf(aReturnType, bReturnType) return typeCheckerContext.isSubtypeOf(aReturnType, bReturnType)
} }
@@ -479,7 +478,7 @@ class IrOverridingUtil(
) )
) return false ) return false
return if (pa.isVar && pb.isVar) { return if (pa.isVar && pb.isVar) {
createTypeChecker( createTypeCheckerState(
a.getter!!.typeParameters, a.getter!!.typeParameters,
b.getter!!.typeParameters b.getter!!.typeParameters
).equalTypes(aReturnType, bReturnType) ).equalTypes(aReturnType, bReturnType)
@@ -674,8 +673,8 @@ class IrOverridingUtil(
return incompatible("Type parameter number mismatch") return incompatible("Type parameter number mismatch")
} }
val typeCheckerContext = val typeCheckerState =
IrTypeCheckerContext( IrTypeCheckerState(
IrTypeSystemContextWithAdditionalAxioms( IrTypeSystemContextWithAdditionalAxioms(
typeSystem, typeSystem,
superTypeParameters, superTypeParameters,
@@ -698,7 +697,7 @@ class IrOverridingUtil(
superValueParameters.forEachIndexed { index, parameter -> superValueParameters.forEachIndexed { index, parameter ->
if (!AbstractTypeChecker.equalTypes( if (!AbstractTypeChecker.equalTypes(
typeCheckerContext as AbstractTypeCheckerContext, typeCheckerState as TypeCheckerState,
subValueParameters[index].type, subValueParameters[index].type,
parameter.type parameter.type
) )
@@ -711,7 +710,7 @@ class IrOverridingUtil(
if (checkReturnType) { if (checkReturnType) {
if (!AbstractTypeChecker.isSubtypeOf( if (!AbstractTypeChecker.isSubtypeOf(
typeCheckerContext as AbstractTypeCheckerContext, typeCheckerState as TypeCheckerState,
subMember.returnType, subMember.returnType,
superMember.returnType superMember.returnType
) )
@@ -7,11 +7,11 @@ package org.jetbrains.kotlin.ir.types
import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.model.KotlinTypeMarker import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.SimpleTypeMarker import org.jetbrains.kotlin.types.model.SimpleTypeMarker
open class IrTypeCheckerContext(override val typeSystemContext: IrTypeSystemContext): AbstractTypeCheckerContext() { open class IrTypeCheckerState(override val typeSystemContext: IrTypeSystemContext): TypeCheckerState() {
val irBuiltIns: IrBuiltIns get() = typeSystemContext.irBuiltIns val irBuiltIns: IrBuiltIns get() = typeSystemContext.irBuiltIns
@@ -21,7 +21,7 @@ open class IrTypeCheckerContext(override val typeSystemContext: IrTypeSystemCont
val typeSubstitutor = IrTypeSubstitutor(parameters, type.arguments, irBuiltIns) val typeSubstitutor = IrTypeSubstitutor(parameters, type.arguments, irBuiltIns)
return object : SupertypesPolicy.DoCustomTransform() { return object : SupertypesPolicy.DoCustomTransform() {
override fun transformType(context: AbstractTypeCheckerContext, type: KotlinTypeMarker): SimpleTypeMarker { override fun transformType(state: TypeCheckerState, type: KotlinTypeMarker): SimpleTypeMarker {
require(type is IrType) require(type is IrType)
return typeSubstitutor.substitute(type) as IrSimpleType return typeSubstitutor.substitute(type) as IrSimpleType
} }
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.types.model.*
@@ -501,10 +501,10 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
} }
override fun newBaseTypeCheckerContext( override fun newTypeCheckerState(
errorTypesEqualToAnything: Boolean, errorTypesEqualToAnything: Boolean,
stubTypesEqualToAnything: Boolean stubTypesEqualToAnything: Boolean
): AbstractTypeCheckerContext = IrTypeCheckerContext(this) ): TypeCheckerState = IrTypeCheckerState(this)
override fun KotlinTypeMarker.isUninferredParameter(): Boolean = false override fun KotlinTypeMarker.isUninferredParameter(): Boolean = false
override fun KotlinTypeMarker.withNullability(nullable: Boolean): KotlinTypeMarker { override fun KotlinTypeMarker.withNullability(nullable: Boolean): KotlinTypeMarker {
@@ -30,7 +30,7 @@ fun IrType.isSubtypeOfClass(superClass: IrClassSymbol): Boolean =
this is IrSimpleType && classifier.isSubtypeOfClass(superClass) this is IrSimpleType && classifier.isSubtypeOfClass(superClass)
fun IrType.isSubtypeOf(superType: IrType, typeSystem: IrTypeSystemContext): Boolean = fun IrType.isSubtypeOf(superType: IrType, typeSystem: IrTypeSystemContext): Boolean =
AbstractTypeChecker.isSubtypeOf(IrTypeCheckerContext(typeSystem), this, superType) AbstractTypeChecker.isSubtypeOf(IrTypeCheckerState(typeSystem), this, superType)
fun IrType.isNullable(): Boolean = fun IrType.isNullable(): Boolean =
when (this) { when (this) {
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.types.AbstractFlexibilityChecker.hasDifferentFlexibi
import org.jetbrains.kotlin.types.AbstractNullabilityChecker import org.jetbrains.kotlin.types.AbstractNullabilityChecker
import org.jetbrains.kotlin.types.AbstractNullabilityChecker.hasPathByNotMarkedNullableNodes import org.jetbrains.kotlin.types.AbstractNullabilityChecker.hasPathByNotMarkedNullableNodes
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.types.model.*
object NewCommonSuperTypeCalculator { object NewCommonSuperTypeCalculator {
@@ -47,14 +47,14 @@ object NewCommonSuperTypeCalculator {
} }
} }
val contextStubTypesEqualToAnything = newBaseTypeCheckerContext(errorTypesEqualToAnything = false, stubTypesEqualToAnything = true) val stateStubTypesEqualToAnything = newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = true)
val contextStubTypesNotEqual = newBaseTypeCheckerContext(errorTypesEqualToAnything = false, stubTypesEqualToAnything = false) val stateStubTypesNotEqual = newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = false)
val lowerSuperType = commonSuperTypeForSimpleTypes(lowers, depth, contextStubTypesEqualToAnything, contextStubTypesNotEqual) val lowerSuperType = commonSuperTypeForSimpleTypes(lowers, depth, stateStubTypesEqualToAnything, stateStubTypesNotEqual)
if (!thereIsFlexibleTypes) return lowerSuperType if (!thereIsFlexibleTypes) return lowerSuperType
val upperSuperType = commonSuperTypeForSimpleTypes( val upperSuperType = commonSuperTypeForSimpleTypes(
types.map { it.upperBoundIfFlexible() }, depth, contextStubTypesEqualToAnything, contextStubTypesNotEqual types.map { it.upperBoundIfFlexible() }, depth, stateStubTypesEqualToAnything, stateStubTypesNotEqual
) )
if (!isTopLevelType) { if (!isTopLevelType) {
@@ -78,8 +78,8 @@ object NewCommonSuperTypeCalculator {
private fun TypeSystemCommonSuperTypesContext.commonSuperTypeForSimpleTypes( private fun TypeSystemCommonSuperTypesContext.commonSuperTypeForSimpleTypes(
types: List<SimpleTypeMarker>, types: List<SimpleTypeMarker>,
depth: Int, depth: Int,
contextStubTypesEqualToAnything: AbstractTypeCheckerContext, stateStubTypesEqualToAnything: TypeCheckerState,
contextStubTypesNotEqual: AbstractTypeCheckerContext stateStubTypesNotEqual: TypeCheckerState
): SimpleTypeMarker { ): SimpleTypeMarker {
if (types.any { it.isError() }) { if (types.any { it.isError() }) {
return createErrorType("CST(${types.joinToString()}") return createErrorType("CST(${types.joinToString()}")
@@ -87,10 +87,10 @@ object NewCommonSuperTypeCalculator {
// i.e. result type also should be marked nullable // i.e. result type also should be marked nullable
val notAllNotNull = val notAllNotNull =
types.any { !isTypeVariable(it) && !AbstractNullabilityChecker.isSubtypeOfAny(contextStubTypesEqualToAnything, it) } types.any { !isTypeVariable(it) && !AbstractNullabilityChecker.isSubtypeOfAny(stateStubTypesEqualToAnything, it) }
val notNullTypes = if (notAllNotNull) types.map { it.withNullability(false) } else types val notNullTypes = if (notAllNotNull) types.map { it.withNullability(false) } else types
val commonSuperType = commonSuperTypeForNotNullTypes(notNullTypes, depth, contextStubTypesEqualToAnything, contextStubTypesNotEqual) val commonSuperType = commonSuperTypeForNotNullTypes(notNullTypes, depth, stateStubTypesEqualToAnything, stateStubTypesNotEqual)
return if (notAllNotNull) return if (notAllNotNull)
refineNullabilityForUndefinedNullability(types, commonSuperType) ?: commonSuperType.withNullability(true) refineNullabilityForUndefinedNullability(types, commonSuperType) ?: commonSuperType.withNullability(true)
else else
@@ -115,12 +115,12 @@ object NewCommonSuperTypeCalculator {
// Makes representative sample, i.e. (A, B, A) -> (A, B) // Makes representative sample, i.e. (A, B, A) -> (A, B)
private fun TypeSystemCommonSuperTypesContext.uniquify( private fun TypeSystemCommonSuperTypesContext.uniquify(
types: List<SimpleTypeMarker>, types: List<SimpleTypeMarker>,
contextStubTypesNotEqual: AbstractTypeCheckerContext stateStubTypesNotEqual: TypeCheckerState
): List<SimpleTypeMarker> { ): List<SimpleTypeMarker> {
val uniqueTypes = arrayListOf<SimpleTypeMarker>() val uniqueTypes = arrayListOf<SimpleTypeMarker>()
for (type in types) { for (type in types) {
val isNewUniqueType = uniqueTypes.all { val isNewUniqueType = uniqueTypes.all {
val equalsModuloFlexibility = AbstractTypeChecker.equalTypes(contextStubTypesNotEqual, it, type) && val equalsModuloFlexibility = AbstractTypeChecker.equalTypes(stateStubTypesNotEqual, it, type) &&
!it.typeConstructor().isIntegerLiteralTypeConstructor() !it.typeConstructor().isIntegerLiteralTypeConstructor()
!equalsModuloFlexibility || hasDifferentFlexibilityAtDepth(listOf(it, type)) !equalsModuloFlexibility || hasDifferentFlexibilityAtDepth(listOf(it, type))
@@ -136,7 +136,7 @@ object NewCommonSuperTypeCalculator {
// Explanation: consider types (A : A0, B : B0, A0, B0), then CST(A, B, A0, B0) == CST(CST(A, A0), CST(B, B0)) == CST(A0, B0) // Explanation: consider types (A : A0, B : B0, A0, B0), then CST(A, B, A0, B0) == CST(CST(A, A0), CST(B, B0)) == CST(A0, B0)
private fun TypeSystemCommonSuperTypesContext.filterSupertypes( private fun TypeSystemCommonSuperTypesContext.filterSupertypes(
list: List<SimpleTypeMarker>, list: List<SimpleTypeMarker>,
contextStubTypesNotEqual: AbstractTypeCheckerContext stateStubTypesNotEqual: TypeCheckerState
): List<SimpleTypeMarker> { ): List<SimpleTypeMarker> {
val supertypes = list.toMutableList() val supertypes = list.toMutableList()
val iterator = supertypes.iterator() val iterator = supertypes.iterator()
@@ -144,7 +144,7 @@ object NewCommonSuperTypeCalculator {
val potentialSubtype = iterator.next() val potentialSubtype = iterator.next()
val isSubtype = supertypes.any { supertype -> val isSubtype = supertypes.any { supertype ->
supertype !== potentialSubtype && supertype !== potentialSubtype &&
AbstractTypeChecker.isSubtypeOf(contextStubTypesNotEqual, potentialSubtype, supertype) && AbstractTypeChecker.isSubtypeOf(stateStubTypesNotEqual, potentialSubtype, supertype) &&
!hasDifferentFlexibilityAtDepth(listOf(potentialSubtype, supertype)) !hasDifferentFlexibilityAtDepth(listOf(potentialSubtype, supertype))
} }
@@ -163,8 +163,8 @@ object NewCommonSuperTypeCalculator {
private fun TypeSystemCommonSuperTypesContext.commonSuperTypeForNotNullTypes( private fun TypeSystemCommonSuperTypesContext.commonSuperTypeForNotNullTypes(
types: List<SimpleTypeMarker>, types: List<SimpleTypeMarker>,
depth: Int, depth: Int,
contextStubTypesEqualToAnything: AbstractTypeCheckerContext, stateStubTypesEqualToAnything: TypeCheckerState,
contextStubTypesNotEqual: AbstractTypeCheckerContext stateStubTypesNotEqual: TypeCheckerState
): SimpleTypeMarker { ): SimpleTypeMarker {
if (types.size == 1) return types.single() if (types.size == 1) return types.single()
@@ -187,20 +187,20 @@ object NewCommonSuperTypeCalculator {
if (uniqueStubTypes.size > 1) return nullableAnyType() if (uniqueStubTypes.size > 1) return nullableAnyType()
if (stubTypeVariables.none { it.isDefinitelyNotNullType() }) { if (stubTypeVariables.none { it.isDefinitelyNotNullType() }) {
return uniquify(stubTypeVariables.ifEmpty { types }, contextStubTypesNotEqual).singleOrNull() ?: return nullableAnyType() return uniquify(stubTypeVariables.ifEmpty { types }, stateStubTypesNotEqual).singleOrNull() ?: return nullableAnyType()
} }
} }
val uniqueTypes = uniquify(nonTypeVariables, contextStubTypesNotEqual) val uniqueTypes = uniquify(nonTypeVariables, stateStubTypesNotEqual)
if (uniqueTypes.size == 1) return uniqueTypes.single() if (uniqueTypes.size == 1) return uniqueTypes.single()
val explicitSupertypes = filterSupertypes(uniqueTypes, contextStubTypesNotEqual) val explicitSupertypes = filterSupertypes(uniqueTypes, stateStubTypesNotEqual)
if (explicitSupertypes.size == 1) return explicitSupertypes.single() if (explicitSupertypes.size == 1) return explicitSupertypes.single()
findErrorTypeInSupertypes(explicitSupertypes, contextStubTypesEqualToAnything)?.let { return it } findErrorTypeInSupertypes(explicitSupertypes, stateStubTypesEqualToAnything)?.let { return it }
findCommonIntegerLiteralTypesSuperType(explicitSupertypes)?.let { return it } findCommonIntegerLiteralTypesSuperType(explicitSupertypes)?.let { return it }
return findSuperTypeConstructorsAndIntersectResult(explicitSupertypes, depth, contextStubTypesEqualToAnything) return findSuperTypeConstructorsAndIntersectResult(explicitSupertypes, depth, stateStubTypesEqualToAnything)
} }
private fun TypeSystemCommonSuperTypesContext.isTypeVariable(type: SimpleTypeMarker): Boolean { private fun TypeSystemCommonSuperTypesContext.isTypeVariable(type: SimpleTypeMarker): Boolean {
@@ -215,10 +215,10 @@ object NewCommonSuperTypeCalculator {
private fun TypeSystemCommonSuperTypesContext.findErrorTypeInSupertypes( private fun TypeSystemCommonSuperTypesContext.findErrorTypeInSupertypes(
types: List<SimpleTypeMarker>, types: List<SimpleTypeMarker>,
contextStubTypesEqualToAnything: AbstractTypeCheckerContext stateStubTypesEqualToAnything: TypeCheckerState
): SimpleTypeMarker? { ): SimpleTypeMarker? {
for (type in types) { for (type in types) {
collectAllSupertypes(type, contextStubTypesEqualToAnything).firstOrNull { it.isError() }?.let { return it.toErrorType() } collectAllSupertypes(type, stateStubTypesEqualToAnything).firstOrNull { it.isError() }?.let { return it.toErrorType() }
} }
return null return null
} }
@@ -226,10 +226,10 @@ object NewCommonSuperTypeCalculator {
private fun TypeSystemCommonSuperTypesContext.findSuperTypeConstructorsAndIntersectResult( private fun TypeSystemCommonSuperTypesContext.findSuperTypeConstructorsAndIntersectResult(
types: List<SimpleTypeMarker>, types: List<SimpleTypeMarker>,
depth: Int, depth: Int,
contextStubTypesEqualToAnything: AbstractTypeCheckerContext stateStubTypesEqualToAnything: TypeCheckerState
): SimpleTypeMarker = ): SimpleTypeMarker =
intersectTypes( intersectTypes(
allCommonSuperTypeConstructors(types, contextStubTypesEqualToAnything) allCommonSuperTypeConstructors(types, stateStubTypesEqualToAnything)
.map { superTypeWithGivenConstructor(types, it, depth) } .map { superTypeWithGivenConstructor(types, it, depth) }
) )
@@ -238,14 +238,14 @@ object NewCommonSuperTypeCalculator {
*/ */
private fun TypeSystemCommonSuperTypesContext.allCommonSuperTypeConstructors( private fun TypeSystemCommonSuperTypesContext.allCommonSuperTypeConstructors(
types: List<SimpleTypeMarker>, types: List<SimpleTypeMarker>,
contextStubTypesEqualToAnything: AbstractTypeCheckerContext stateStubTypesEqualToAnything: TypeCheckerState
): List<TypeConstructorMarker> { ): List<TypeConstructorMarker> {
val result = collectAllSupertypes(types.first(), contextStubTypesEqualToAnything) val result = collectAllSupertypes(types.first(), stateStubTypesEqualToAnything)
// retain all super constructors of the first type that are present in the supertypes of all other types // retain all super constructors of the first type that are present in the supertypes of all other types
for (type in types) { for (type in types) {
if (type === types.first()) continue if (type === types.first()) continue
result.retainAll(collectAllSupertypes(type, contextStubTypesEqualToAnything)) result.retainAll(collectAllSupertypes(type, stateStubTypesEqualToAnything))
} }
// remove all constructors that have subtype(s) with constructors from the resulting set - they are less precise // remove all constructors that have subtype(s) with constructors from the resulting set - they are less precise
return result.filterNot { target -> return result.filterNot { target ->
@@ -257,13 +257,13 @@ object NewCommonSuperTypeCalculator {
private fun TypeSystemCommonSuperTypesContext.collectAllSupertypes( private fun TypeSystemCommonSuperTypesContext.collectAllSupertypes(
type: SimpleTypeMarker, type: SimpleTypeMarker,
contextStubTypesEqualToAnything: AbstractTypeCheckerContext stateStubTypesEqualToAnything: TypeCheckerState
) = ) =
LinkedHashSet<TypeConstructorMarker>().apply { LinkedHashSet<TypeConstructorMarker>().apply {
contextStubTypesEqualToAnything.anySupertype( stateStubTypesEqualToAnything.anySupertype(
type, type,
{ add(it.typeConstructor()); false }, { add(it.typeConstructor()); false },
{ AbstractTypeCheckerContext.SupertypesPolicy.LowerIfFlexible } { TypeCheckerState.SupertypesPolicy.LowerIfFlexible }
) )
} }
@@ -278,7 +278,7 @@ object NewCommonSuperTypeCalculator {
nullable = false nullable = false
) )
val typeCheckerContext = newBaseTypeCheckerContext(errorTypesEqualToAnything = false, stubTypesEqualToAnything = true) val typeCheckerContext = newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = true)
/** /**
* Sometimes one type can have several supertypes with given type constructor, suppose A <: List<Int> and A <: List<Double>. * Sometimes one type can have several supertypes with given type constructor, suppose A <: List<Int> and A <: List<Double>.
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.*
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind.* import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind.*
import org.jetbrains.kotlin.types.AbstractTypeApproximator import org.jetbrains.kotlin.types.AbstractTypeApproximator
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.types.model.*
import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.SmartList
@@ -43,23 +43,23 @@ class ConstraintInjector(
fun addInitialSubtypeConstraint(c: Context, lowerType: KotlinTypeMarker, upperType: KotlinTypeMarker, position: ConstraintPosition) { fun addInitialSubtypeConstraint(c: Context, lowerType: KotlinTypeMarker, upperType: KotlinTypeMarker, position: ConstraintPosition) {
val initialConstraint = InitialConstraint(lowerType, upperType, UPPER, position).also { c.addInitialConstraint(it) } val initialConstraint = InitialConstraint(lowerType, upperType, UPPER, position).also { c.addInitialConstraint(it) }
val typeCheckerContext = TypeCheckerContext(c, IncorporationConstraintPosition(position, initialConstraint)) val typeCheckerState = TypeCheckerStateForConstraintInjector(c, IncorporationConstraintPosition(position, initialConstraint))
updateAllowedTypeDepth(c, lowerType) updateAllowedTypeDepth(c, lowerType)
updateAllowedTypeDepth(c, upperType) updateAllowedTypeDepth(c, upperType)
addSubTypeConstraintAndIncorporateIt(c, lowerType, upperType, typeCheckerContext) addSubTypeConstraintAndIncorporateIt(c, lowerType, upperType, typeCheckerState)
} }
private fun Context.addInitialEqualityConstraintThroughSubtyping( private fun Context.addInitialEqualityConstraintThroughSubtyping(
a: KotlinTypeMarker, a: KotlinTypeMarker,
b: KotlinTypeMarker, b: KotlinTypeMarker,
typeCheckerContext: TypeCheckerContext typeCheckerState: TypeCheckerStateForConstraintInjector
) { ) {
updateAllowedTypeDepth(this, a) updateAllowedTypeDepth(this, a)
updateAllowedTypeDepth(this, b) updateAllowedTypeDepth(this, b)
addSubTypeConstraintAndIncorporateIt(this, a, b, typeCheckerContext) addSubTypeConstraintAndIncorporateIt(this, a, b, typeCheckerState)
addSubTypeConstraintAndIncorporateIt(this, b, a, typeCheckerContext) addSubTypeConstraintAndIncorporateIt(this, b, a, typeCheckerState)
} }
fun addInitialEqualityConstraint(c: Context, a: KotlinTypeMarker, b: KotlinTypeMarker, position: ConstraintPosition) = with(c) { fun addInitialEqualityConstraint(c: Context, a: KotlinTypeMarker, b: KotlinTypeMarker, position: ConstraintPosition) = with(c) {
@@ -69,32 +69,32 @@ class ConstraintInjector(
else -> return else -> return
} }
val initialConstraint = InitialConstraint(typeVariable, equalType, EQUALITY, position).also { c.addInitialConstraint(it) } val initialConstraint = InitialConstraint(typeVariable, equalType, EQUALITY, position).also { c.addInitialConstraint(it) }
val typeCheckerContext = TypeCheckerContext(c, IncorporationConstraintPosition(position, initialConstraint)) val typeCheckerState = TypeCheckerStateForConstraintInjector(c, IncorporationConstraintPosition(position, initialConstraint))
// We add constraints like `T? == Foo!` in the old way // We add constraints like `T? == Foo!` in the old way
if (!typeVariable.isSimpleType() || typeVariable.isMarkedNullable()) { if (!typeVariable.isSimpleType() || typeVariable.isMarkedNullable()) {
addInitialEqualityConstraintThroughSubtyping(typeVariable, equalType, typeCheckerContext) addInitialEqualityConstraintThroughSubtyping(typeVariable, equalType, typeCheckerState)
return return
} }
updateAllowedTypeDepth(c, equalType) updateAllowedTypeDepth(c, equalType)
addEqualityConstraintAndIncorporateIt(c, typeVariable, equalType, typeCheckerContext) addEqualityConstraintAndIncorporateIt(c, typeVariable, equalType, typeCheckerState)
} }
private fun addSubTypeConstraintAndIncorporateIt( private fun addSubTypeConstraintAndIncorporateIt(
c: Context, c: Context,
lowerType: KotlinTypeMarker, lowerType: KotlinTypeMarker,
upperType: KotlinTypeMarker, upperType: KotlinTypeMarker,
typeCheckerContext: TypeCheckerContext typeCheckerState: TypeCheckerStateForConstraintInjector
) { ) {
typeCheckerContext.setConstrainingTypesToPrintDebugInfo(lowerType, upperType) typeCheckerState.setConstrainingTypesToPrintDebugInfo(lowerType, upperType)
typeCheckerContext.runIsSubtypeOf(lowerType, upperType) typeCheckerState.runIsSubtypeOf(lowerType, upperType)
// Missed constraints are constraints which we skipped in the constraints processor by mistake (incorrect optimization) // Missed constraints are constraints which we skipped in the constraints processor by mistake (incorrect optimization)
val missedConstraints = processConstraints(c, typeCheckerContext) val missedConstraints = processConstraints(c, typeCheckerState)
if (missedConstraints != null) { if (missedConstraints != null) {
c.addMissedConstraints(typeCheckerContext.position, missedConstraints) c.addMissedConstraints(typeCheckerState.position, missedConstraints)
} }
} }
@@ -102,16 +102,16 @@ class ConstraintInjector(
c: Context, c: Context,
typeVariable: KotlinTypeMarker, typeVariable: KotlinTypeMarker,
equalType: KotlinTypeMarker, equalType: KotlinTypeMarker,
typeCheckerContext: TypeCheckerContext typeCheckerState: TypeCheckerStateForConstraintInjector
) { ) {
typeCheckerContext.setConstrainingTypesToPrintDebugInfo(typeVariable, equalType) typeCheckerState.setConstrainingTypesToPrintDebugInfo(typeVariable, equalType)
typeCheckerContext.addEqualityConstraint(typeVariable.typeConstructor(c), equalType) typeCheckerState.addEqualityConstraint(typeVariable.typeConstructor(c), equalType)
// Missed constraints are constraints which we skipped in the constraints processor by mistake (incorrect optimization) // Missed constraints are constraints which we skipped in the constraints processor by mistake (incorrect optimization)
val missedConstraints = processConstraints(c, typeCheckerContext) val missedConstraints = processConstraints(c, typeCheckerState)
if (missedConstraints != null) { if (missedConstraints != null) {
c.addMissedConstraints(typeCheckerContext.position, missedConstraints) c.addMissedConstraints(typeCheckerState.position, missedConstraints)
} }
} }
@@ -126,23 +126,23 @@ class ConstraintInjector(
// If proper constraints processing is enabled, then we don't have missed constraints // If proper constraints processing is enabled, then we don't have missed constraints
if (properConstraintsProcessingEnabled) return if (properConstraintsProcessingEnabled) return
val typeCheckerContext = TypeCheckerContext(c, position) val typeCheckerState = TypeCheckerStateForConstraintInjector(c, position)
for ((variable, constraint) in missedConstraints) { for ((variable, constraint) in missedConstraints) {
typeCheckerContext.addPossibleNewConstraint(variable, constraint) typeCheckerState.addPossibleNewConstraint(variable, constraint)
} }
processConstraints(c, typeCheckerContext, skipProperEqualityConstraints = false) processConstraints(c, typeCheckerState, skipProperEqualityConstraints = false)
} }
private fun processConstraints( private fun processConstraints(
c: Context, c: Context,
typeCheckerContext: TypeCheckerContext, typeCheckerState: TypeCheckerStateForConstraintInjector,
skipProperEqualityConstraints: Boolean = true skipProperEqualityConstraints: Boolean = true
): MutableList<Pair<TypeVariableMarker, Constraint>>? { ): MutableList<Pair<TypeVariableMarker, Constraint>>? {
val properConstraintsProcessingEnabled = val properConstraintsProcessingEnabled =
languageVersionSettings.supportsFeature(LanguageFeature.ProperTypeInferenceConstraintsProcessing) languageVersionSettings.supportsFeature(LanguageFeature.ProperTypeInferenceConstraintsProcessing)
while (typeCheckerContext.hasConstraintsToProcess()) { while (typeCheckerState.hasConstraintsToProcess()) {
processGivenConstraints(c, typeCheckerContext, typeCheckerContext.extractAllConstraints()!!) processGivenConstraints(c, typeCheckerState, typeCheckerState.extractAllConstraints()!!)
val contextOps = c as? ConstraintSystemOperation val contextOps = c as? ConstraintSystemOperation
@@ -157,21 +157,21 @@ class ConstraintInjector(
} }
} }
if (hasProperEqualityConstraintForEachVariable) return typeCheckerContext.extractAllConstraints() if (hasProperEqualityConstraintForEachVariable) return typeCheckerState.extractAllConstraints()
} }
return null return null
} }
private fun processGivenConstraints( private fun processGivenConstraints(
c: Context, c: Context,
typeCheckerContext: TypeCheckerContext, typeCheckerState: TypeCheckerStateForConstraintInjector,
constraintsToProcess: MutableList<Pair<TypeVariableMarker, Constraint>> constraintsToProcess: MutableList<Pair<TypeVariableMarker, Constraint>>
) { ) {
for ((typeVariable, constraint) in constraintsToProcess) { for ((typeVariable, constraint) in constraintsToProcess) {
if (c.shouldWeSkipConstraint(typeVariable, constraint)) continue if (c.shouldWeSkipConstraint(typeVariable, constraint)) continue
val constraints = val constraints =
c.notFixedTypeVariables[typeVariable.freshTypeConstructor(c)] ?: typeCheckerContext.fixedTypeVariable(typeVariable) c.notFixedTypeVariables[typeVariable.freshTypeConstructor(c)] ?: typeCheckerState.fixedTypeVariable(typeVariable)
// it is important, that we add constraint here(not inside TypeCheckerContext), because inside incorporation we read constraints // it is important, that we add constraint here(not inside TypeCheckerContext), because inside incorporation we read constraints
val (addedOrNonRedundantExistedConstraint, wasAdded) = constraints.addConstraint(constraint) val (addedOrNonRedundantExistedConstraint, wasAdded) = constraints.addConstraint(constraint)
@@ -184,7 +184,7 @@ class ConstraintInjector(
} }
if (constraintToIncorporate != null) { if (constraintToIncorporate != null) {
constraintIncorporator.incorporate(typeCheckerContext, typeVariable, constraintToIncorporate) constraintIncorporator.incorporate(typeCheckerState, typeVariable, constraintToIncorporate)
} }
} }
} }
@@ -217,8 +217,8 @@ class ConstraintInjector(
private fun Context.isAllowedType(type: KotlinTypeMarker) = private fun Context.isAllowedType(type: KotlinTypeMarker) =
type.typeDepth() <= maxTypeDepthFromInitialConstraints + ALLOWED_DEPTH_DELTA_FOR_INCORPORATION type.typeDepth() <= maxTypeDepthFromInitialConstraints + ALLOWED_DEPTH_DELTA_FOR_INCORPORATION
private inner class TypeCheckerContext(val c: Context, val position: IncorporationConstraintPosition) : private inner class TypeCheckerStateForConstraintInjector(val c: Context, val position: IncorporationConstraintPosition) :
AbstractTypeCheckerContextForConstraintSystem(c), ConstraintIncorporator.Context, TypeSystemInferenceExtensionContext by c { TypeCheckerStateForConstraintSystem(c), ConstraintIncorporator.Context, TypeSystemInferenceExtensionContext by c {
// We use `var` intentionally to avoid extra allocations as this property is quite "hot" // We use `var` intentionally to avoid extra allocations as this property is quite "hot"
private var possibleNewConstraints: MutableList<Pair<TypeVariableMarker, Constraint>>? = null private var possibleNewConstraints: MutableList<Pair<TypeVariableMarker, Constraint>>? = null
@@ -245,10 +245,10 @@ class ConstraintInjector(
baseUpperType = upperType baseUpperType = upperType
} }
val baseContext: AbstractTypeCheckerContext = newBaseTypeCheckerContext(isErrorTypeEqualsToAnything, isStubTypeEqualsToAnything) val baseState: TypeCheckerState = newTypeCheckerState(isErrorTypeEqualsToAnything, isStubTypeEqualsToAnything)
override fun substitutionSupertypePolicy(type: SimpleTypeMarker): SupertypesPolicy { override fun substitutionSupertypePolicy(type: SimpleTypeMarker): SupertypesPolicy {
return baseContext.substitutionSupertypePolicy(type) return baseState.substitutionSupertypePolicy(type)
} }
override fun refineType(type: KotlinTypeMarker): KotlinTypeMarker { override fun refineType(type: KotlinTypeMarker): KotlinTypeMarker {
@@ -257,7 +257,7 @@ class ConstraintInjector(
} }
} }
override fun prepareType(type: KotlinTypeMarker) = baseContext.prepareType(type) override fun prepareType(type: KotlinTypeMarker) = baseState.prepareType(type)
fun runIsSubtypeOf( fun runIsSubtypeOf(
lowerType: KotlinTypeMarker, lowerType: KotlinTypeMarker,
@@ -267,7 +267,7 @@ class ConstraintInjector(
) { ) {
fun isSubtypeOf(upperType: KotlinTypeMarker) = fun isSubtypeOf(upperType: KotlinTypeMarker) =
AbstractTypeChecker.isSubtypeOf( AbstractTypeChecker.isSubtypeOf(
this@TypeCheckerContext as AbstractTypeCheckerContext, this@TypeCheckerStateForConstraintInjector as TypeCheckerState,
lowerType, lowerType,
upperType, upperType,
isFromNullabilityConstraint isFromNullabilityConstraint
@@ -7,11 +7,11 @@ package org.jetbrains.kotlin.resolve.calls.inference.components
import org.jetbrains.kotlin.types.AbstractNullabilityChecker import org.jetbrains.kotlin.types.AbstractNullabilityChecker
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.types.model.*
abstract class AbstractTypeCheckerContextForConstraintSystem(override val typeSystemContext: TypeSystemInferenceExtensionContext) : abstract class TypeCheckerStateForConstraintSystem(override val typeSystemContext: TypeSystemInferenceExtensionContext) :
AbstractTypeCheckerContext() { TypeCheckerState() {
override val KotlinTypeMarker.isAllowedTypeVariable: Boolean override val KotlinTypeMarker.isAllowedTypeVariable: Boolean
get() = false get() = false
@@ -99,10 +99,10 @@ abstract class AbstractTypeCheckerContextForConstraintSystem(override val typeSy
} }
private fun KotlinTypeMarker.isTypeVariableWithExact() = private fun KotlinTypeMarker.isTypeVariableWithExact() =
with(typeSystemContext) { hasExactAnnotation() } && anyBound(this@AbstractTypeCheckerContextForConstraintSystem::isMyTypeVariable) with(typeSystemContext) { hasExactAnnotation() } && anyBound(this@TypeCheckerStateForConstraintSystem::isMyTypeVariable)
private fun KotlinTypeMarker.isTypeVariableWithNoInfer() = private fun KotlinTypeMarker.isTypeVariableWithNoInfer() =
with(typeSystemContext) { hasNoInferAnnotation() } && anyBound(this@AbstractTypeCheckerContextForConstraintSystem::isMyTypeVariable) with(typeSystemContext) { hasNoInferAnnotation() } && anyBound(this@TypeCheckerStateForConstraintSystem::isMyTypeVariable)
private fun internalAddSubtypeConstraint( private fun internalAddSubtypeConstraint(
subType: KotlinTypeMarker, subType: KotlinTypeMarker,
@@ -333,7 +333,7 @@ abstract class AbstractTypeCheckerContextForConstraintSystem(override val typeSy
} }
private fun isSubtypeOfByTypeChecker(subType: KotlinTypeMarker, superType: KotlinTypeMarker) = private fun isSubtypeOfByTypeChecker(subType: KotlinTypeMarker, superType: KotlinTypeMarker) =
AbstractTypeChecker.isSubtypeOf(this as AbstractTypeCheckerContext, subType, superType) AbstractTypeChecker.isSubtypeOf(this as TypeCheckerState, subType, superType)
private fun assertInputTypes(subType: KotlinTypeMarker, superType: KotlinTypeMarker) = with(typeSystemContext) { private fun assertInputTypes(subType: KotlinTypeMarker, superType: KotlinTypeMarker) = with(typeSystemContext) {
if (!AbstractTypeChecker.RUN_SLOW_ASSERTIONS) return if (!AbstractTypeChecker.RUN_SLOW_ASSERTIONS) return
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.resolve.calls.inference.model package org.jetbrains.kotlin.resolve.calls.inference.model
import org.jetbrains.kotlin.resolve.calls.inference.components.AbstractTypeCheckerContextForConstraintSystem
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemUtilContext import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemUtilContext
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.types.model.*
@@ -174,7 +174,7 @@ abstract class AbstractTypeApproximator(
val needApproximate = conf.localTypes && constructor.isLocalType() val needApproximate = conf.localTypes && constructor.isLocalType()
if (!needApproximate) return null if (!needApproximate) return null
val superConstructor = constructor.supertypes().first().typeConstructor() val superConstructor = constructor.supertypes().first().typeConstructor()
val typeCheckerContext = newBaseTypeCheckerContext( val typeCheckerContext = newTypeCheckerState(
errorTypesEqualToAnything = false, errorTypesEqualToAnything = false,
stubTypesEqualToAnything = false stubTypesEqualToAnything = false
) )
@@ -305,7 +305,7 @@ object ExpectedActualResolver {
kotlinTypeRefiner: KotlinTypeRefiner, kotlinTypeRefiner: KotlinTypeRefiner,
): Boolean { ): Boolean {
with(NewKotlinTypeCheckerImpl(kotlinTypeRefiner)) { with(NewKotlinTypeCheckerImpl(kotlinTypeRefiner)) {
return ClassicTypeCheckerContext( return ClassicTypeCheckerState(
errorTypeEqualsToAnything = false, errorTypeEqualsToAnything = false,
typeSystemContext = typeSystemContext, typeSystemContext = typeSystemContext,
kotlinTypeRefiner = kotlinTypeRefiner, kotlinTypeRefiner = kotlinTypeRefiner,
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.types.AbstractNullabilityChecker
import org.jetbrains.kotlin.types.KotlinTypeFactory import org.jetbrains.kotlin.types.KotlinTypeFactory
import org.jetbrains.kotlin.types.SimpleType import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.TypeIntersector import org.jetbrains.kotlin.types.TypeIntersector
import org.jetbrains.kotlin.types.checker.ClassicTypeCheckerContext import org.jetbrains.kotlin.types.checker.ClassicTypeCheckerState
class SlowTypeAssertionsEnabledTest : KotlinTestWithEnvironmentManagement() { class SlowTypeAssertionsEnabledTest : KotlinTestWithEnvironmentManagement() {
@@ -45,7 +45,7 @@ class SlowTypeAssertionsEnabledTest : KotlinTestWithEnvironmentManagement() {
try { try {
val superType = TypeIntersector.intersectTypes(listOf(builtIns.charSequence.defaultType, builtIns.comparable.defaultType)) val superType = TypeIntersector.intersectTypes(listOf(builtIns.charSequence.defaultType, builtIns.comparable.defaultType))
AbstractNullabilityChecker.isPossibleSubtype( AbstractNullabilityChecker.isPossibleSubtype(
ClassicTypeCheckerContext(errorTypeEqualsToAnything = true), builtIns.annotationType, ClassicTypeCheckerState(errorTypeEqualsToAnything = true), builtIns.annotationType,
superType as SimpleType superType as SimpleType
) )
} catch (e: AssertionError) { } catch (e: AssertionError) {
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.descriptors
import org.jetbrains.kotlin.descriptors.EffectiveVisibility.Permissiveness import org.jetbrains.kotlin.descriptors.EffectiveVisibility.Permissiveness
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.model.TypeCheckerProviderContext import org.jetbrains.kotlin.types.model.TypeCheckerProviderContext
import org.jetbrains.kotlin.types.model.TypeConstructorMarker import org.jetbrains.kotlin.types.model.TypeConstructorMarker
@@ -261,7 +261,7 @@ internal fun containerRelation(
} }
} }
private fun TypeCheckerProviderContext.createTypeCheckerContext(): AbstractTypeCheckerContext = newBaseTypeCheckerContext( private fun TypeCheckerProviderContext.createTypeCheckerContext(): TypeCheckerState = newTypeCheckerState(
errorTypesEqualToAnything = false, errorTypesEqualToAnything = false,
stubTypesEqualToAnything = true stubTypesEqualToAnything = true
) )
@@ -5,8 +5,8 @@
package org.jetbrains.kotlin.types package org.jetbrains.kotlin.types
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext.LowerCapturedTypePolicy.* import org.jetbrains.kotlin.types.TypeCheckerState.LowerCapturedTypePolicy.*
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext.SupertypesPolicy import org.jetbrains.kotlin.types.TypeCheckerState.SupertypesPolicy
import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.types.model.*
import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.kotlin.utils.SmartSet import org.jetbrains.kotlin.utils.SmartSet
@@ -14,14 +14,14 @@ import java.util.*
/** /**
* Context that defines how type-checker operates, stores type-checker state, * Context that defines how type-checker operates, stores type-checker state,
* created by [TypeCheckerProviderContext.newBaseTypeCheckerContext] in most cases * created by [TypeCheckerProviderContext.newTypeCheckerState] in most cases
* *
* Stateful and shouldn't be reused * Stateful and shouldn't be reused
* *
* Once some type-checker operation is performed using a [TypeCheckerProviderContext], for example a [AbstractTypeChecker.isSubtypeOf], * Once some type-checker operation is performed using a [TypeCheckerProviderContext], for example a [AbstractTypeChecker.isSubtypeOf],
* new instance of particular [AbstractTypeCheckerContext] should be created, with properly specified type system context * new instance of particular [TypeCheckerState] should be created, with properly specified type system context
*/ */
abstract class AbstractTypeCheckerContext() { abstract class TypeCheckerState {
abstract val typeSystemContext: TypeSystemContext abstract val typeSystemContext: TypeSystemContext
@@ -43,7 +43,7 @@ abstract class AbstractTypeCheckerContext() {
protected var argumentsDepth = 0 protected var argumentsDepth = 0
internal inline fun <T> runWithArgumentsSettings(subArgument: KotlinTypeMarker, f: AbstractTypeCheckerContext.() -> T): T { internal inline fun <T> runWithArgumentsSettings(subArgument: KotlinTypeMarker, f: TypeCheckerState.() -> T): T {
if (argumentsDepth > 100) { if (argumentsDepth > 100) {
error("Arguments depth is too high. Some related argument: $subArgument") error("Arguments depth is too high. Some related argument: $subArgument")
} }
@@ -134,21 +134,21 @@ abstract class AbstractTypeCheckerContext() {
} }
sealed class SupertypesPolicy { sealed class SupertypesPolicy {
abstract fun transformType(context: AbstractTypeCheckerContext, type: KotlinTypeMarker): SimpleTypeMarker abstract fun transformType(state: TypeCheckerState, type: KotlinTypeMarker): SimpleTypeMarker
object None : SupertypesPolicy() { object None : SupertypesPolicy() {
override fun transformType(context: AbstractTypeCheckerContext, type: KotlinTypeMarker) = override fun transformType(state: TypeCheckerState, type: KotlinTypeMarker) =
throw UnsupportedOperationException("Should not be called") throw UnsupportedOperationException("Should not be called")
} }
object UpperIfFlexible : SupertypesPolicy() { object UpperIfFlexible : SupertypesPolicy() {
override fun transformType(context: AbstractTypeCheckerContext, type: KotlinTypeMarker) = override fun transformType(state: TypeCheckerState, type: KotlinTypeMarker) =
with(context.typeSystemContext) { type.upperBoundIfFlexible() } with(state.typeSystemContext) { type.upperBoundIfFlexible() }
} }
object LowerIfFlexible : SupertypesPolicy() { object LowerIfFlexible : SupertypesPolicy() {
override fun transformType(context: AbstractTypeCheckerContext, type: KotlinTypeMarker) = override fun transformType(state: TypeCheckerState, type: KotlinTypeMarker) =
with(context.typeSystemContext) { type.lowerBoundIfFlexible() } with(state.typeSystemContext) { type.lowerBoundIfFlexible() }
} }
abstract class DoCustomTransform : SupertypesPolicy() abstract class DoCustomTransform : SupertypesPolicy()
@@ -168,7 +168,7 @@ object AbstractTypeChecker {
context: TypeCheckerProviderContext, context: TypeCheckerProviderContext,
type: KotlinTypeMarker, type: KotlinTypeMarker,
stubTypesEqualToAnything: Boolean = true stubTypesEqualToAnything: Boolean = true
) = context.newBaseTypeCheckerContext(true, stubTypesEqualToAnything).prepareType(type) ) = context.newTypeCheckerState(true, stubTypesEqualToAnything).prepareType(type)
fun isSubtypeOf( fun isSubtypeOf(
context: TypeCheckerProviderContext, context: TypeCheckerProviderContext,
@@ -176,18 +176,18 @@ object AbstractTypeChecker {
superType: KotlinTypeMarker, superType: KotlinTypeMarker,
stubTypesEqualToAnything: Boolean = true stubTypesEqualToAnything: Boolean = true
): Boolean { ): Boolean {
return isSubtypeOf(context.newBaseTypeCheckerContext(true, stubTypesEqualToAnything), subType, superType) return isSubtypeOf(context.newTypeCheckerState(true, stubTypesEqualToAnything), subType, superType)
} }
fun isSubtypeOfClass( fun isSubtypeOfClass(
context: AbstractTypeCheckerContext, state: TypeCheckerState,
typeConstructor: TypeConstructorMarker, typeConstructor: TypeConstructorMarker,
superConstructor: TypeConstructorMarker superConstructor: TypeConstructorMarker
): Boolean { ): Boolean {
if (typeConstructor == superConstructor) return true if (typeConstructor == superConstructor) return true
with(context.typeSystemContext) { with(state.typeSystemContext) {
for (superType in typeConstructor.supertypes()) { for (superType in typeConstructor.supertypes()) {
if (isSubtypeOfClass(context, superType.typeConstructor(), superConstructor)) { if (isSubtypeOfClass(state, superType.typeConstructor(), superConstructor)) {
return true return true
} }
} }
@@ -201,29 +201,29 @@ object AbstractTypeChecker {
b: KotlinTypeMarker, b: KotlinTypeMarker,
stubTypesEqualToAnything: Boolean = true stubTypesEqualToAnything: Boolean = true
): Boolean { ): Boolean {
return equalTypes(context.newBaseTypeCheckerContext(false, stubTypesEqualToAnything), a, b) return equalTypes(context.newTypeCheckerState(false, stubTypesEqualToAnything), a, b)
} }
fun isSubtypeOf( fun isSubtypeOf(
context: AbstractTypeCheckerContext, state: TypeCheckerState,
subType: KotlinTypeMarker, subType: KotlinTypeMarker,
superType: KotlinTypeMarker, superType: KotlinTypeMarker,
isFromNullabilityConstraint: Boolean = false isFromNullabilityConstraint: Boolean = false
): Boolean { ): Boolean {
if (subType === superType) return true if (subType === superType) return true
if (!context.customIsSubtypeOf(subType, superType)) return false if (!state.customIsSubtypeOf(subType, superType)) return false
return completeIsSubTypeOf(context, subType, superType, isFromNullabilityConstraint) return completeIsSubTypeOf(state, subType, superType, isFromNullabilityConstraint)
} }
fun equalTypes(context: AbstractTypeCheckerContext, a: KotlinTypeMarker, b: KotlinTypeMarker): Boolean = fun equalTypes(state: TypeCheckerState, a: KotlinTypeMarker, b: KotlinTypeMarker): Boolean =
with(context.typeSystemContext) { with(state.typeSystemContext) {
if (a === b) return true if (a === b) return true
if (isCommonDenotableType(a) && isCommonDenotableType(b)) { if (isCommonDenotableType(a) && isCommonDenotableType(b)) {
val refinedA = context.prepareType(context.refineType(a)) val refinedA = state.prepareType(state.refineType(a))
val refinedB = context.prepareType(context.refineType(b)) val refinedB = state.prepareType(state.refineType(b))
val simpleA = refinedA.lowerBoundIfFlexible() val simpleA = refinedA.lowerBoundIfFlexible()
if (!areEqualTypeConstructors(refinedA.typeConstructor(), refinedB.typeConstructor())) return false if (!areEqualTypeConstructors(refinedA.typeConstructor(), refinedB.typeConstructor())) return false
if (simpleA.argumentsCount() == 0) { if (simpleA.argumentsCount() == 0) {
@@ -233,40 +233,40 @@ object AbstractTypeChecker {
} }
} }
return isSubtypeOf(context, a, b) && isSubtypeOf(context, b, a) return isSubtypeOf(state, a, b) && isSubtypeOf(state, b, a)
} }
private fun completeIsSubTypeOf( private fun completeIsSubTypeOf(
context: AbstractTypeCheckerContext, state: TypeCheckerState,
subType: KotlinTypeMarker, subType: KotlinTypeMarker,
superType: KotlinTypeMarker, superType: KotlinTypeMarker,
isFromNullabilityConstraint: Boolean isFromNullabilityConstraint: Boolean
): Boolean = with(context.typeSystemContext) { ): Boolean = with(state.typeSystemContext) {
val preparedSubType = context.prepareType(context.refineType(subType)) val preparedSubType = state.prepareType(state.refineType(subType))
val preparedSuperType = context.prepareType(context.refineType(superType)) val preparedSuperType = state.prepareType(state.refineType(superType))
checkSubtypeForSpecialCases(context, preparedSubType.lowerBoundIfFlexible(), preparedSuperType.upperBoundIfFlexible())?.let { checkSubtypeForSpecialCases(state, preparedSubType.lowerBoundIfFlexible(), preparedSuperType.upperBoundIfFlexible())?.let {
context.addSubtypeConstraint(preparedSubType, preparedSuperType, isFromNullabilityConstraint) state.addSubtypeConstraint(preparedSubType, preparedSuperType, isFromNullabilityConstraint)
return it return it
} }
// we should add constraints with flexible types, otherwise we never get flexible type as answer in constraint system // we should add constraints with flexible types, otherwise we never get flexible type as answer in constraint system
context.addSubtypeConstraint(preparedSubType, preparedSuperType, isFromNullabilityConstraint)?.let { return it } state.addSubtypeConstraint(preparedSubType, preparedSuperType, isFromNullabilityConstraint)?.let { return it }
return isSubtypeOfForSingleClassifierType(context, preparedSubType.lowerBoundIfFlexible(), preparedSuperType.upperBoundIfFlexible()) return isSubtypeOfForSingleClassifierType(state, preparedSubType.lowerBoundIfFlexible(), preparedSuperType.upperBoundIfFlexible())
} }
private fun checkSubtypeForIntegerLiteralType( private fun checkSubtypeForIntegerLiteralType(
context: AbstractTypeCheckerContext, state: TypeCheckerState,
subType: SimpleTypeMarker, subType: SimpleTypeMarker,
superType: SimpleTypeMarker superType: SimpleTypeMarker
): Boolean? = with(context.typeSystemContext) { ): Boolean? = with(state.typeSystemContext) {
if (!subType.isIntegerLiteralType() && !superType.isIntegerLiteralType()) return null if (!subType.isIntegerLiteralType() && !superType.isIntegerLiteralType()) return null
fun isTypeInIntegerLiteralType(integerLiteralType: SimpleTypeMarker, type: SimpleTypeMarker, checkSupertypes: Boolean): Boolean = fun isTypeInIntegerLiteralType(integerLiteralType: SimpleTypeMarker, type: SimpleTypeMarker, checkSupertypes: Boolean): Boolean =
integerLiteralType.possibleIntegerTypes().any { possibleType -> integerLiteralType.possibleIntegerTypes().any { possibleType ->
(possibleType.typeConstructor() == type.typeConstructor()) || (checkSupertypes && isSubtypeOf(context, type, possibleType)) (possibleType.typeConstructor() == type.typeConstructor()) || (checkSupertypes && isSubtypeOf(state, type, possibleType))
} }
fun isIntegerLiteralTypeInIntersectionComponents(type: SimpleTypeMarker): Boolean { fun isIntegerLiteralTypeInIntersectionComponents(type: SimpleTypeMarker): Boolean {
@@ -299,12 +299,12 @@ object AbstractTypeChecker {
return null return null
} }
private fun hasNothingSupertype(context: AbstractTypeCheckerContext, type: SimpleTypeMarker): Boolean = with(context.typeSystemContext) { private fun hasNothingSupertype(state: TypeCheckerState, type: SimpleTypeMarker): Boolean = with(state.typeSystemContext) {
val typeConstructor = type.typeConstructor() val typeConstructor = type.typeConstructor()
if (typeConstructor.isClassTypeConstructor()) { if (typeConstructor.isClassTypeConstructor()) {
return typeConstructor.isNothingConstructor() return typeConstructor.isNothingConstructor()
} }
return context.anySupertype(type, { it.typeConstructor().isNothingConstructor() }) { return state.anySupertype(type, { it.typeConstructor().isNothingConstructor() }) {
if (it.isClassType()) { if (it.isClassType()) {
SupertypesPolicy.None SupertypesPolicy.None
} else { } else {
@@ -314,23 +314,23 @@ object AbstractTypeChecker {
} }
private fun isSubtypeOfForSingleClassifierType( private fun isSubtypeOfForSingleClassifierType(
context: AbstractTypeCheckerContext, state: TypeCheckerState,
subType: SimpleTypeMarker, subType: SimpleTypeMarker,
superType: SimpleTypeMarker superType: SimpleTypeMarker
): Boolean = with(context.typeSystemContext) { ): Boolean = with(state.typeSystemContext) {
if (AbstractTypeChecker.RUN_SLOW_ASSERTIONS) { if (RUN_SLOW_ASSERTIONS) {
assert(subType.isSingleClassifierType() || subType.typeConstructor().isIntersection() || context.isAllowedTypeVariable(subType)) { assert(subType.isSingleClassifierType() || subType.typeConstructor().isIntersection() || state.isAllowedTypeVariable(subType)) {
"Not singleClassifierType and not intersection subType: $subType" "Not singleClassifierType and not intersection subType: $subType"
} }
assert(superType.isSingleClassifierType() || context .isAllowedTypeVariable(superType)) { assert(superType.isSingleClassifierType() || state .isAllowedTypeVariable(superType)) {
"Not singleClassifierType superType: $superType" "Not singleClassifierType superType: $superType"
} }
} }
if (!AbstractNullabilityChecker.isPossibleSubtype(context, subType, superType)) return false if (!AbstractNullabilityChecker.isPossibleSubtype(state, subType, superType)) return false
checkSubtypeForIntegerLiteralType(context, subType.lowerBoundIfFlexible(), superType.upperBoundIfFlexible())?.let { checkSubtypeForIntegerLiteralType(state, subType.lowerBoundIfFlexible(), superType.upperBoundIfFlexible())?.let {
context.addSubtypeConstraint(subType, superType) state.addSubtypeConstraint(subType, superType)
return it return it
} }
@@ -339,11 +339,11 @@ object AbstractTypeChecker {
if (areEqualTypeConstructors(subType.typeConstructor(), superConstructor) && superConstructor.parametersCount() == 0) return true if (areEqualTypeConstructors(subType.typeConstructor(), superConstructor) && superConstructor.parametersCount() == 0) return true
if (superType.typeConstructor().isAnyConstructor()) return true if (superType.typeConstructor().isAnyConstructor()) return true
val supertypesWithSameConstructor = findCorrespondingSupertypes(context, subType, superConstructor) val supertypesWithSameConstructor = findCorrespondingSupertypes(state, subType, superConstructor)
.map { context.prepareType(it).asSimpleType() ?: it } .map { state.prepareType(it).asSimpleType() ?: it }
when (supertypesWithSameConstructor.size) { when (supertypesWithSameConstructor.size) {
0 -> return hasNothingSupertype(context, subType) // todo Nothing & Array<Number> <: Array<String> 0 -> return hasNothingSupertype(state, subType) // todo Nothing & Array<Number> <: Array<String>
1 -> return context.isSubtypeForSameConstructor(supertypesWithSameConstructor.first().asArgumentList(), superType) 1 -> return state.isSubtypeForSameConstructor(supertypesWithSameConstructor.first().asArgumentList(), superType)
else -> { // at least 2 supertypes with same constructors. Such case is rare else -> { // at least 2 supertypes with same constructors. Such case is rare
val newArguments = ArgumentList(superConstructor.parametersCount()) val newArguments = ArgumentList(superConstructor.parametersCount())
@@ -361,10 +361,10 @@ object AbstractTypeChecker {
newArguments.add(intersection) newArguments.add(intersection)
} }
if (!anyNonOutParameter && context.isSubtypeForSameConstructor(newArguments, superType)) return true if (!anyNonOutParameter && state.isSubtypeForSameConstructor(newArguments, superType)) return true
// TODO: rethink this; now components order in intersection type affects semantic due to run subtyping (which can add constraints) only until the first successful candidate // TODO: rethink this; now components order in intersection type affects semantic due to run subtyping (which can add constraints) only until the first successful candidate
return supertypesWithSameConstructor.any { context.isSubtypeForSameConstructor(it.asArgumentList(), superType) } return supertypesWithSameConstructor.any { state.isSubtypeForSameConstructor(it.asArgumentList(), superType) }
} }
} }
} }
@@ -388,7 +388,7 @@ object AbstractTypeChecker {
return typeVariableConstructor.typeParameter?.hasRecursiveBounds(selfConstructor) == true return typeVariableConstructor.typeParameter?.hasRecursiveBounds(selfConstructor) == true
} }
fun AbstractTypeCheckerContext.isSubtypeForSameConstructor( fun TypeCheckerState.isSubtypeForSameConstructor(
capturedSubArguments: TypeArgumentListMarker, capturedSubArguments: TypeArgumentListMarker,
superType: SimpleTypeMarker superType: SimpleTypeMarker
): Boolean = with(this.typeSystemContext) { ): Boolean = with(this.typeSystemContext) {
@@ -474,12 +474,12 @@ object AbstractTypeChecker {
} }
private fun checkSubtypeForSpecialCases( private fun checkSubtypeForSpecialCases(
context: AbstractTypeCheckerContext, state: TypeCheckerState,
subType: SimpleTypeMarker, subType: SimpleTypeMarker,
superType: SimpleTypeMarker superType: SimpleTypeMarker
): Boolean? = with(context.typeSystemContext) { ): Boolean? = with(state.typeSystemContext) {
if (subType.isError() || superType.isError()) { if (subType.isError() || superType.isError()) {
if (context.isErrorTypeEqualsToAnything) return true if (state.isErrorTypeEqualsToAnything) return true
if (subType.isMarkedNullable() && !superType.isMarkedNullable()) return false if (subType.isMarkedNullable() && !superType.isMarkedNullable()) return false
@@ -491,10 +491,10 @@ object AbstractTypeChecker {
} }
if (subType.isStubTypeForBuilderInference() && superType.isStubTypeForBuilderInference()) if (subType.isStubTypeForBuilderInference() && superType.isStubTypeForBuilderInference())
return isStubTypeSubtypeOfAnother(subType, superType) || context.isStubTypeEqualsToAnything return isStubTypeSubtypeOfAnother(subType, superType) || state.isStubTypeEqualsToAnything
if (subType.isStubType() || superType.isStubType()) if (subType.isStubType() || superType.isStubType())
return context.isStubTypeEqualsToAnything return state.isStubTypeEqualsToAnything
// superType might be a definitely notNull type (see KT-42824) // superType might be a definitely notNull type (see KT-42824)
val superOriginalType = superType.asDefinitelyNotNullType()?.original() ?: superType val superOriginalType = superType.asDefinitelyNotNullType()?.original() ?: superType
@@ -508,9 +508,9 @@ object AbstractTypeChecker {
} else { } else {
if (superType.isDefinitelyNotNullType()) lowerType.makeDefinitelyNotNullOrNotNull() else lowerType if (superType.isDefinitelyNotNullType()) lowerType.makeDefinitelyNotNullOrNotNull() else lowerType
} }
when (context.getLowerCapturedTypePolicy(subType, superTypeCaptured)) { when (state.getLowerCapturedTypePolicy(subType, superTypeCaptured)) {
CHECK_ONLY_LOWER -> return isSubtypeOf(context, subType, nullableLowerType) CHECK_ONLY_LOWER -> return isSubtypeOf(state, subType, nullableLowerType)
CHECK_SUBTYPE_AND_LOWER -> if (isSubtypeOf(context, subType, nullableLowerType)) return true CHECK_SUBTYPE_AND_LOWER -> if (isSubtypeOf(state, subType, nullableLowerType)) return true
SKIP_LOWER -> Unit SKIP_LOWER -> Unit
} }
} }
@@ -519,7 +519,7 @@ object AbstractTypeChecker {
if (superTypeConstructor.isIntersection()) { if (superTypeConstructor.isIntersection()) {
assert(!superType.isMarkedNullable()) { "Intersection type should not be marked nullable!: $superType" } assert(!superType.isMarkedNullable()) { "Intersection type should not be marked nullable!: $superType" }
return superTypeConstructor.supertypes().all { isSubtypeOf(context, subType, it) } return superTypeConstructor.supertypes().all { isSubtypeOf(state, subType, it) }
} }
/* /*
@@ -532,7 +532,7 @@ object AbstractTypeChecker {
if (subType is CapturedTypeMarker if (subType is CapturedTypeMarker
|| (subTypeConstructor.isIntersection() && subTypeConstructor.supertypes().all { it is CapturedTypeMarker })) { || (subTypeConstructor.isIntersection() && subTypeConstructor.supertypes().all { it is CapturedTypeMarker })) {
val typeParameter = val typeParameter =
context.typeSystemContext.getTypeParameterForArgumentInBaseIfItEqualToTarget(baseType = superType, targetType = subType) state.typeSystemContext.getTypeParameterForArgumentInBaseIfItEqualToTarget(baseType = superType, targetType = subType)
if (typeParameter != null && typeParameter.hasRecursiveBounds(superType.typeConstructor())) { if (typeParameter != null && typeParameter.hasRecursiveBounds(superType.typeConstructor())) {
return true return true
} }
@@ -561,10 +561,10 @@ object AbstractTypeChecker {
} }
private fun collectAllSupertypesWithGivenTypeConstructor( private fun collectAllSupertypesWithGivenTypeConstructor(
context: AbstractTypeCheckerContext, state: TypeCheckerState,
subType: SimpleTypeMarker, subType: SimpleTypeMarker,
superConstructor: TypeConstructorMarker superConstructor: TypeConstructorMarker
): List<SimpleTypeMarker> = with(context.typeSystemContext) { ): List<SimpleTypeMarker> = with(state.typeSystemContext) {
subType.fastCorrespondingSupertypes(superConstructor)?.let { subType.fastCorrespondingSupertypes(superConstructor)?.let {
return it return it
} }
@@ -580,7 +580,7 @@ object AbstractTypeChecker {
val result: MutableList<SimpleTypeMarker> = SmartList() val result: MutableList<SimpleTypeMarker> = SmartList()
context.anySupertype(subType, { false }) { state.anySupertype(subType, { false }) {
val current = captureFromArguments(it, CaptureStatus.FOR_SUBTYPING) ?: it val current = captureFromArguments(it, CaptureStatus.FOR_SUBTYPING) ?: it
@@ -593,7 +593,7 @@ object AbstractTypeChecker {
SupertypesPolicy.LowerIfFlexible SupertypesPolicy.LowerIfFlexible
} }
else -> { else -> {
context.substitutionSupertypePolicy(current) state.substitutionSupertypePolicy(current)
} }
} }
} }
@@ -602,11 +602,11 @@ object AbstractTypeChecker {
} }
private fun collectAndFilter( private fun collectAndFilter(
context: AbstractTypeCheckerContext, state: TypeCheckerState,
classType: SimpleTypeMarker, classType: SimpleTypeMarker,
constructor: TypeConstructorMarker constructor: TypeConstructorMarker
) = ) =
selectOnlyPureKotlinSupertypes(context, collectAllSupertypesWithGivenTypeConstructor(context, classType, constructor)) selectOnlyPureKotlinSupertypes(state, collectAllSupertypesWithGivenTypeConstructor(state, classType, constructor))
/** /**
@@ -620,9 +620,9 @@ object AbstractTypeChecker {
* More tests: javaAndKotlinSuperType & purelyImplementedCollection folder * More tests: javaAndKotlinSuperType & purelyImplementedCollection folder
*/ */
private fun selectOnlyPureKotlinSupertypes( private fun selectOnlyPureKotlinSupertypes(
context: AbstractTypeCheckerContext, state: TypeCheckerState,
supertypes: List<SimpleTypeMarker> supertypes: List<SimpleTypeMarker>
): List<SimpleTypeMarker> = with(context.typeSystemContext) { ): List<SimpleTypeMarker> = with(state.typeSystemContext) {
if (supertypes.size < 2) return supertypes if (supertypes.size < 2) return supertypes
val allPureSupertypes = supertypes.filter { val allPureSupertypes = supertypes.filter {
@@ -635,22 +635,22 @@ object AbstractTypeChecker {
// nullability was checked earlier via nullabilityChecker // nullability was checked earlier via nullabilityChecker
// should be used only if you really sure that it is correct // should be used only if you really sure that it is correct
fun findCorrespondingSupertypes( fun findCorrespondingSupertypes(
context: AbstractTypeCheckerContext, state: TypeCheckerState,
subType: SimpleTypeMarker, subType: SimpleTypeMarker,
superConstructor: TypeConstructorMarker superConstructor: TypeConstructorMarker
): List<SimpleTypeMarker> = with(context.typeSystemContext) { ): List<SimpleTypeMarker> = with(state.typeSystemContext) {
if (subType.isClassType()) { if (subType.isClassType()) {
return collectAndFilter(context, subType, superConstructor) return collectAndFilter(state, subType, superConstructor)
} }
// i.e. superType is not a classType // i.e. superType is not a classType
if (!superConstructor.isClassTypeConstructor() && !superConstructor.isIntegerLiteralTypeConstructor()) { if (!superConstructor.isClassTypeConstructor() && !superConstructor.isIntegerLiteralTypeConstructor()) {
return collectAllSupertypesWithGivenTypeConstructor(context, subType, superConstructor) return collectAllSupertypesWithGivenTypeConstructor(state, subType, superConstructor)
} }
// todo add tests // todo add tests
val classTypeSupertypes = SmartList<SimpleTypeMarker>() val classTypeSupertypes = SmartList<SimpleTypeMarker>()
context.anySupertype(subType, { false }) { state.anySupertype(subType, { false }) {
if (it.isClassType()) { if (it.isClassType()) {
classTypeSupertypes.add(it) classTypeSupertypes.add(it)
SupertypesPolicy.None SupertypesPolicy.None
@@ -659,42 +659,42 @@ object AbstractTypeChecker {
} }
} }
return classTypeSupertypes.flatMap { collectAndFilter(context, it, superConstructor) } return classTypeSupertypes.flatMap { collectAndFilter(state, it, superConstructor) }
} }
} }
object AbstractNullabilityChecker { object AbstractNullabilityChecker {
// this method checks only nullability // this method checks only nullability
fun isPossibleSubtype(context: AbstractTypeCheckerContext, subType: SimpleTypeMarker, superType: SimpleTypeMarker): Boolean = fun isPossibleSubtype(state: TypeCheckerState, subType: SimpleTypeMarker, superType: SimpleTypeMarker): Boolean =
runIsPossibleSubtype(context, subType, superType) runIsPossibleSubtype(state, subType, superType)
fun isSubtypeOfAny(context: TypeCheckerProviderContext, type: KotlinTypeMarker): Boolean = fun isSubtypeOfAny(context: TypeCheckerProviderContext, type: KotlinTypeMarker): Boolean =
AbstractNullabilityChecker.isSubtypeOfAny( AbstractNullabilityChecker.isSubtypeOfAny(
context.newBaseTypeCheckerContext( context.newTypeCheckerState(
errorTypesEqualToAnything = false, errorTypesEqualToAnything = false,
stubTypesEqualToAnything = true stubTypesEqualToAnything = true
), ),
type type
) )
fun isSubtypeOfAny(context: AbstractTypeCheckerContext, type: KotlinTypeMarker): Boolean = fun isSubtypeOfAny(state: TypeCheckerState, type: KotlinTypeMarker): Boolean =
with(context.typeSystemContext) { with(state.typeSystemContext) {
context.hasNotNullSupertype(type.lowerBoundIfFlexible(), SupertypesPolicy.LowerIfFlexible) state.hasNotNullSupertype(type.lowerBoundIfFlexible(), SupertypesPolicy.LowerIfFlexible)
} }
private fun runIsPossibleSubtype(context: AbstractTypeCheckerContext, subType: SimpleTypeMarker, superType: SimpleTypeMarker): Boolean = private fun runIsPossibleSubtype(state: TypeCheckerState, subType: SimpleTypeMarker, superType: SimpleTypeMarker): Boolean =
with(context.typeSystemContext) { with(state.typeSystemContext) {
if (AbstractTypeChecker.RUN_SLOW_ASSERTIONS) { if (AbstractTypeChecker.RUN_SLOW_ASSERTIONS) {
// it makes for case String? & Any <: String // it makes for case String? & Any <: String
assert( assert(
subType.isSingleClassifierType() || subType.typeConstructor().isIntersection() || context.isAllowedTypeVariable( subType.isSingleClassifierType() || subType.typeConstructor().isIntersection() || state.isAllowedTypeVariable(
subType subType
) )
) { ) {
"Not singleClassifierType and not intersection subType: $subType" "Not singleClassifierType and not intersection subType: $subType"
} }
assert(superType.isSingleClassifierType() || context.isAllowedTypeVariable(superType)) { assert(superType.isSingleClassifierType() || state.isAllowedTypeVariable(superType)) {
"Not singleClassifierType superType: $superType" "Not singleClassifierType superType: $superType"
} }
} }
@@ -709,13 +709,13 @@ object AbstractNullabilityChecker {
if (subType is CapturedTypeMarker && subType.isProjectionNotNull()) return true if (subType is CapturedTypeMarker && subType.isProjectionNotNull()) return true
// i.e. subType is not-nullable // i.e. subType is not-nullable
if (context.hasNotNullSupertype(subType, SupertypesPolicy.LowerIfFlexible)) return true if (state.hasNotNullSupertype(subType, SupertypesPolicy.LowerIfFlexible)) return true
// i.e. subType hasn't not-null supertype and isn't definitely not-null, but superType is definitely not-null // i.e. subType hasn't not-null supertype and isn't definitely not-null, but superType is definitely not-null
if (superType.isDefinitelyNotNullType()) return false if (superType.isDefinitelyNotNullType()) return false
// i.e subType hasn't not-null supertype, but superType has // i.e subType hasn't not-null supertype, but superType has
if (context.hasNotNullSupertype(superType, SupertypesPolicy.UpperIfFlexible)) return false if (state.hasNotNullSupertype(superType, SupertypesPolicy.UpperIfFlexible)) return false
// both superType and subType hasn't not-null supertype and are not definitely not null. // both superType and subType hasn't not-null supertype and are not definitely not null.
@@ -731,10 +731,10 @@ object AbstractNullabilityChecker {
// classType cannot has special type in supertype list // classType cannot has special type in supertype list
if (subType.isClassType()) return false if (subType.isClassType()) return false
return hasPathByNotMarkedNullableNodes(context, subType, superType.typeConstructor()) return hasPathByNotMarkedNullableNodes(state, subType, superType.typeConstructor())
} }
fun AbstractTypeCheckerContext.hasNotNullSupertype(type: SimpleTypeMarker, supertypesPolicy: SupertypesPolicy) = fun TypeCheckerState.hasNotNullSupertype(type: SimpleTypeMarker, supertypesPolicy: SupertypesPolicy) =
with(typeSystemContext) { with(typeSystemContext) {
anySupertype(type, { anySupertype(type, {
(it.isClassType() && !it.isMarkedNullable()) || it.isDefinitelyNotNullType() (it.isClassType() && !it.isMarkedNullable()) || it.isDefinitelyNotNullType()
@@ -745,24 +745,24 @@ object AbstractNullabilityChecker {
fun TypeCheckerProviderContext.hasPathByNotMarkedNullableNodes(start: SimpleTypeMarker, end: TypeConstructorMarker) = fun TypeCheckerProviderContext.hasPathByNotMarkedNullableNodes(start: SimpleTypeMarker, end: TypeConstructorMarker) =
hasPathByNotMarkedNullableNodes( hasPathByNotMarkedNullableNodes(
newBaseTypeCheckerContext(errorTypesEqualToAnything = false, stubTypesEqualToAnything = true), start, end newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = true), start, end
) )
fun hasPathByNotMarkedNullableNodes(context: AbstractTypeCheckerContext, start: SimpleTypeMarker, end: TypeConstructorMarker) = fun hasPathByNotMarkedNullableNodes(state: TypeCheckerState, start: SimpleTypeMarker, end: TypeConstructorMarker) =
with(context.typeSystemContext) { with(state.typeSystemContext) {
context.anySupertype( state.anySupertype(
start, start,
{ isApplicableAsEndNode(context, it, end) }, { isApplicableAsEndNode(state, it, end) },
{ if (it.isMarkedNullable()) SupertypesPolicy.None else SupertypesPolicy.LowerIfFlexible } { if (it.isMarkedNullable()) SupertypesPolicy.None else SupertypesPolicy.LowerIfFlexible }
) )
} }
private fun isApplicableAsEndNode(context: AbstractTypeCheckerContext, type: SimpleTypeMarker, end: TypeConstructorMarker): Boolean = private fun isApplicableAsEndNode(state: TypeCheckerState, type: SimpleTypeMarker, end: TypeConstructorMarker): Boolean =
with(context.typeSystemContext) { with(state.typeSystemContext) {
if (type.isNothing()) return true if (type.isNothing()) return true
if (type.isMarkedNullable()) return false if (type.isMarkedNullable()) return false
if (context.isStubTypeEqualsToAnything && type.isStubType()) return true if (state.isStubTypeEqualsToAnything && type.isStubType()) return true
return areEqualTypeConstructors(type.typeConstructor(), end) return areEqualTypeConstructors(type.typeConstructor(), end)
} }
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.types.model package org.jetbrains.kotlin.types.model
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract import kotlin.contracts.contract
@@ -91,14 +91,14 @@ interface TypeSystemTypeFactoryContext: TypeSystemBuiltInsContext {
} }
/** /**
* Factory, that constructs [AbstractTypeCheckerContext], which defines type-checker behaviour * Factory, that constructs [TypeCheckerState], which defines type-checker behaviour
* Implementation is recommended to be [TypeSystemContext] * Implementation is recommended to be [TypeSystemContext]
*/ */
interface TypeCheckerProviderContext { interface TypeCheckerProviderContext {
fun newBaseTypeCheckerContext( fun newTypeCheckerState(
errorTypesEqualToAnything: Boolean, errorTypesEqualToAnything: Boolean,
stubTypesEqualToAnything: Boolean stubTypesEqualToAnything: Boolean
): AbstractTypeCheckerContext ): TypeCheckerState
} }
/** /**
@@ -107,11 +107,11 @@ interface TypeCheckerProviderContext {
interface TypeSystemCommonSuperTypesContext : TypeSystemContext, TypeSystemTypeFactoryContext, TypeCheckerProviderContext { interface TypeSystemCommonSuperTypesContext : TypeSystemContext, TypeSystemTypeFactoryContext, TypeCheckerProviderContext {
fun KotlinTypeMarker.anySuperTypeConstructor(predicate: (TypeConstructorMarker) -> Boolean) = fun KotlinTypeMarker.anySuperTypeConstructor(predicate: (TypeConstructorMarker) -> Boolean) =
newBaseTypeCheckerContext(errorTypesEqualToAnything = false, stubTypesEqualToAnything = true) newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = true)
.anySupertype( .anySupertype(
lowerBoundIfFlexible(), lowerBoundIfFlexible(),
{ predicate(it.typeConstructor()) }, { predicate(it.typeConstructor()) },
{ AbstractTypeCheckerContext.SupertypesPolicy.LowerIfFlexible } { TypeCheckerState.SupertypesPolicy.LowerIfFlexible }
) )
fun KotlinTypeMarker.canHaveUndefinedNullability(): Boolean fun KotlinTypeMarker.canHaveUndefinedNullability(): Boolean
@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.types.*; import org.jetbrains.kotlin.types.*;
import org.jetbrains.kotlin.types.checker.*; import org.jetbrains.kotlin.types.checker.*;
import org.jetbrains.kotlin.types.model.TypeConstructorMarker;
import org.jetbrains.kotlin.utils.SmartSet; import org.jetbrains.kotlin.utils.SmartSet;
import java.util.*; import java.util.*;
@@ -309,7 +308,7 @@ public class OverridingUtil {
return OverrideCompatibilityInfo.conflict("Type parameter number mismatch"); return OverrideCompatibilityInfo.conflict("Type parameter number mismatch");
} }
Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerContext> typeChecker = createTypeChecker(superTypeParameters, subTypeParameters); Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerState> typeChecker = createTypeChecker(superTypeParameters, subTypeParameters);
for (int i = 0; i < superTypeParameters.size(); i++) { for (int i = 0; i < superTypeParameters.size(); i++) {
if (!areTypeParametersEquivalent( if (!areTypeParametersEquivalent(
@@ -385,7 +384,7 @@ public class OverridingUtil {
} }
@NotNull @NotNull
private Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerContext> createTypeChecker( private Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerState> createTypeChecker(
@NotNull List<TypeParameterDescriptor> firstParameters, @NotNull List<TypeParameterDescriptor> firstParameters,
@NotNull List<TypeParameterDescriptor> secondParameters @NotNull List<TypeParameterDescriptor> secondParameters
) { ) {
@@ -393,19 +392,19 @@ public class OverridingUtil {
"Should be the same number of type parameters: " + firstParameters + " vs " + secondParameters; "Should be the same number of type parameters: " + firstParameters + " vs " + secondParameters;
NewKotlinTypeCheckerImpl typeChecker = new NewKotlinTypeCheckerImpl(kotlinTypeRefiner, KotlinTypePreparator.Default.INSTANCE); NewKotlinTypeCheckerImpl typeChecker = new NewKotlinTypeCheckerImpl(kotlinTypeRefiner, KotlinTypePreparator.Default.INSTANCE);
ClassicTypeCheckerContext context = createTypeCheckerContext(firstParameters, secondParameters); ClassicTypeCheckerState context = createTypeCheckerContext(firstParameters, secondParameters);
return new Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerContext>(typeChecker, context); return new Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerState>(typeChecker, context);
} }
@NotNull @NotNull
private ClassicTypeCheckerContext createTypeCheckerContext( private ClassicTypeCheckerState createTypeCheckerContext(
@NotNull List<TypeParameterDescriptor> firstParameters, @NotNull List<TypeParameterDescriptor> firstParameters,
@NotNull List<TypeParameterDescriptor> secondParameters @NotNull List<TypeParameterDescriptor> secondParameters
) { ) {
if (firstParameters.isEmpty()) { if (firstParameters.isEmpty()) {
return (ClassicTypeCheckerContext) new OverridingUtilTypeSystemContext(null, equalityAxioms, kotlinTypeRefiner) return (ClassicTypeCheckerState) new OverridingUtilTypeSystemContext(null, equalityAxioms, kotlinTypeRefiner)
.newBaseTypeCheckerContext(true, true); .newTypeCheckerState(true, true);
} }
Map<TypeConstructor, TypeConstructor> matchingTypeConstructors = new HashMap<TypeConstructor, TypeConstructor>(); Map<TypeConstructor, TypeConstructor> matchingTypeConstructors = new HashMap<TypeConstructor, TypeConstructor>();
@@ -413,8 +412,8 @@ public class OverridingUtil {
matchingTypeConstructors.put(firstParameters.get(i).getTypeConstructor(), secondParameters.get(i).getTypeConstructor()); matchingTypeConstructors.put(firstParameters.get(i).getTypeConstructor(), secondParameters.get(i).getTypeConstructor());
} }
return (ClassicTypeCheckerContext) new OverridingUtilTypeSystemContext(matchingTypeConstructors, equalityAxioms, kotlinTypeRefiner) return (ClassicTypeCheckerState) new OverridingUtilTypeSystemContext(matchingTypeConstructors, equalityAxioms, kotlinTypeRefiner)
.newBaseTypeCheckerContext(true, true); .newTypeCheckerState(true, true);
} }
@Nullable @Nullable
@@ -436,7 +435,7 @@ public class OverridingUtil {
private boolean areTypesEquivalent( private boolean areTypesEquivalent(
@NotNull KotlinType typeInSuper, @NotNull KotlinType typeInSuper,
@NotNull KotlinType typeInSub, @NotNull KotlinType typeInSub,
@NotNull Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerContext> typeChecker @NotNull Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerState> typeChecker
) { ) {
boolean bothErrors = KotlinTypeKt.isError(typeInSuper) && KotlinTypeKt.isError(typeInSub); boolean bothErrors = KotlinTypeKt.isError(typeInSuper) && KotlinTypeKt.isError(typeInSub);
if (bothErrors) return true; if (bothErrors) return true;
@@ -447,7 +446,7 @@ public class OverridingUtil {
private boolean areTypeParametersEquivalent( private boolean areTypeParametersEquivalent(
@NotNull TypeParameterDescriptor superTypeParameter, @NotNull TypeParameterDescriptor superTypeParameter,
@NotNull TypeParameterDescriptor subTypeParameter, @NotNull TypeParameterDescriptor subTypeParameter,
@NotNull Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerContext> typeChecker @NotNull Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerState> typeChecker
) { ) {
List<KotlinType> superBounds = superTypeParameter.getUpperBounds(); List<KotlinType> superBounds = superTypeParameter.getUpperBounds();
List<KotlinType> subBounds = new ArrayList<KotlinType>(subTypeParameter.getUpperBounds()); List<KotlinType> subBounds = new ArrayList<KotlinType>(subTypeParameter.getUpperBounds());
@@ -585,7 +584,7 @@ public class OverridingUtil {
if (!isVisibilityMoreSpecific(a, b)) return false; if (!isVisibilityMoreSpecific(a, b)) return false;
Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerContext> checker = Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerState> checker =
DEFAULT.createTypeChecker(a.getTypeParameters(), b.getTypeParameters()); DEFAULT.createTypeChecker(a.getTypeParameters(), b.getTypeParameters());
if (a instanceof FunctionDescriptor) { if (a instanceof FunctionDescriptor) {
@@ -642,7 +641,7 @@ public class OverridingUtil {
@NotNull KotlinType aReturnType, @NotNull KotlinType aReturnType,
@NotNull CallableDescriptor b, @NotNull CallableDescriptor b,
@NotNull KotlinType bReturnType, @NotNull KotlinType bReturnType,
@NotNull Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerContext> typeChecker @NotNull Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerState> typeChecker
) { ) {
return typeChecker.getFirst().isSubtypeOf(typeChecker.getSecond(), aReturnType.unwrap(), bReturnType.unwrap()); return typeChecker.getFirst().isSubtypeOf(typeChecker.getSecond(), aReturnType.unwrap(), bReturnType.unwrap());
} }
@@ -5,9 +5,9 @@
package org.jetbrains.kotlin.resolve package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.TypeConstructor import org.jetbrains.kotlin.types.TypeConstructor
import org.jetbrains.kotlin.types.checker.ClassicTypeCheckerContext import org.jetbrains.kotlin.types.checker.ClassicTypeCheckerState
import org.jetbrains.kotlin.types.checker.ClassicTypeSystemContext import org.jetbrains.kotlin.types.checker.ClassicTypeSystemContext
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
@@ -25,11 +25,11 @@ class OverridingUtilTypeSystemContext(
return super.areEqualTypeConstructors(c1, c2) || areEqualTypeConstructorsByAxioms(c1, c2) return super.areEqualTypeConstructors(c1, c2) || areEqualTypeConstructorsByAxioms(c1, c2)
} }
override fun newBaseTypeCheckerContext( override fun newTypeCheckerState(
errorTypesEqualToAnything: Boolean, errorTypesEqualToAnything: Boolean,
stubTypesEqualToAnything: Boolean stubTypesEqualToAnything: Boolean
): AbstractTypeCheckerContext { ): TypeCheckerState {
return ClassicTypeCheckerContext( return ClassicTypeCheckerState(
errorTypesEqualToAnything, errorTypesEqualToAnything,
stubTypesEqualToAnything, stubTypesEqualToAnything,
allowedTypeVariable = true, allowedTypeVariable = true,
@@ -21,14 +21,14 @@ import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.SimpleTypeMarker import org.jetbrains.kotlin.types.model.SimpleTypeMarker
import org.jetbrains.kotlin.types.refinement.TypeRefinement import org.jetbrains.kotlin.types.refinement.TypeRefinement
open class ClassicTypeCheckerContext( open class ClassicTypeCheckerState(
val errorTypeEqualsToAnything: Boolean, val errorTypeEqualsToAnything: Boolean,
val stubTypeEqualsToAnything: Boolean = true, val stubTypeEqualsToAnything: Boolean = true,
val allowedTypeVariable: Boolean = true, val allowedTypeVariable: Boolean = true,
val kotlinTypeRefiner: KotlinTypeRefiner = KotlinTypeRefiner.Default, val kotlinTypeRefiner: KotlinTypeRefiner = KotlinTypeRefiner.Default,
val kotlinTypePreparator: KotlinTypePreparator = KotlinTypePreparator.Default, val kotlinTypePreparator: KotlinTypePreparator = KotlinTypePreparator.Default,
override val typeSystemContext: ClassicTypeSystemContext = SimpleClassicTypeSystemContext override val typeSystemContext: ClassicTypeSystemContext = SimpleClassicTypeSystemContext
) : AbstractTypeCheckerContext() { ) : TypeCheckerState() {
@OptIn(TypeRefinement::class) @OptIn(TypeRefinement::class)
override fun refineType(type: KotlinTypeMarker): KotlinTypeMarker { override fun refineType(type: KotlinTypeMarker): KotlinTypeMarker {
@@ -59,7 +59,7 @@ open class ClassicTypeCheckerContext(
val substitutor = TypeConstructorSubstitution.create(type).buildSubstitutor() val substitutor = TypeConstructorSubstitution.create(type).buildSubstitutor()
return object : SupertypesPolicy.DoCustomTransform() { return object : SupertypesPolicy.DoCustomTransform() {
override fun transformType(context: AbstractTypeCheckerContext, type: KotlinTypeMarker): SimpleTypeMarker { override fun transformType(state: TypeCheckerState, type: KotlinTypeMarker): SimpleTypeMarker {
return substitutor.safeSubstitute( return substitutor.safeSubstitute(
type.lowerBoundIfFlexible() as KotlinType, type.lowerBoundIfFlexible() as KotlinType,
Variance.INVARIANT Variance.INVARIANT
@@ -388,11 +388,11 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
} }
override fun newBaseTypeCheckerContext( override fun newTypeCheckerState(
errorTypesEqualToAnything: Boolean, errorTypesEqualToAnything: Boolean,
stubTypesEqualToAnything: Boolean stubTypesEqualToAnything: Boolean
): AbstractTypeCheckerContext { ): TypeCheckerState {
return ClassicTypeCheckerContext(errorTypesEqualToAnything, stubTypesEqualToAnything, typeSystemContext = this) return ClassicTypeCheckerState(errorTypesEqualToAnything, stubTypesEqualToAnything, typeSystemContext = this)
} }
override fun nullableNothingType(): SimpleTypeMarker { override fun nullableNothingType(): SimpleTypeMarker {
@@ -21,14 +21,10 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.resolve.OverridingUtil import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.calls.inference.CapturedType import org.jetbrains.kotlin.resolve.calls.inference.CapturedType
import org.jetbrains.kotlin.resolve.calls.inference.CapturedTypeConstructorImpl
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstructor
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.AbstractNullabilityChecker.hasNotNullSupertype import org.jetbrains.kotlin.types.AbstractNullabilityChecker.hasNotNullSupertype
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext.SupertypesPolicy import org.jetbrains.kotlin.types.TypeCheckerState.SupertypesPolicy
import org.jetbrains.kotlin.types.model.CaptureStatus
import org.jetbrains.kotlin.types.typeUtil.makeNullable
object SimpleClassicTypeSystemContext : ClassicTypeSystemContext object SimpleClassicTypeSystemContext : ClassicTypeSystemContext
@@ -53,10 +49,10 @@ object StrictEqualityTypeChecker {
object ErrorTypesAreEqualToAnything : KotlinTypeChecker { object ErrorTypesAreEqualToAnything : KotlinTypeChecker {
override fun isSubtypeOf(subtype: KotlinType, supertype: KotlinType): Boolean = override fun isSubtypeOf(subtype: KotlinType, supertype: KotlinType): Boolean =
NewKotlinTypeChecker.Default.run { ClassicTypeCheckerContext(true).isSubtypeOf(subtype.unwrap(), supertype.unwrap()) } NewKotlinTypeChecker.Default.run { ClassicTypeCheckerState(true).isSubtypeOf(subtype.unwrap(), supertype.unwrap()) }
override fun equalTypes(a: KotlinType, b: KotlinType): Boolean = override fun equalTypes(a: KotlinType, b: KotlinType): Boolean =
NewKotlinTypeChecker.Default.run { ClassicTypeCheckerContext(true).equalTypes(a.unwrap(), b.unwrap()) } NewKotlinTypeChecker.Default.run { ClassicTypeCheckerState(true).equalTypes(a.unwrap(), b.unwrap()) }
} }
interface NewKotlinTypeChecker : KotlinTypeChecker { interface NewKotlinTypeChecker : KotlinTypeChecker {
@@ -77,21 +73,21 @@ class NewKotlinTypeCheckerImpl(
override val overridingUtil: OverridingUtil = OverridingUtil.createWithTypeRefiner(kotlinTypeRefiner) override val overridingUtil: OverridingUtil = OverridingUtil.createWithTypeRefiner(kotlinTypeRefiner)
override fun isSubtypeOf(subtype: KotlinType, supertype: KotlinType): Boolean = override fun isSubtypeOf(subtype: KotlinType, supertype: KotlinType): Boolean =
ClassicTypeCheckerContext( ClassicTypeCheckerState(
true, kotlinTypeRefiner = kotlinTypeRefiner, kotlinTypePreparator = kotlinTypePreparator true, kotlinTypeRefiner = kotlinTypeRefiner, kotlinTypePreparator = kotlinTypePreparator
).isSubtypeOf(subtype.unwrap(), supertype.unwrap()) // todo fix flag errorTypeEqualsToAnything ).isSubtypeOf(subtype.unwrap(), supertype.unwrap()) // todo fix flag errorTypeEqualsToAnything
override fun equalTypes(a: KotlinType, b: KotlinType): Boolean = override fun equalTypes(a: KotlinType, b: KotlinType): Boolean =
ClassicTypeCheckerContext( ClassicTypeCheckerState(
false, kotlinTypeRefiner = kotlinTypeRefiner, kotlinTypePreparator = kotlinTypePreparator false, kotlinTypeRefiner = kotlinTypeRefiner, kotlinTypePreparator = kotlinTypePreparator
).equalTypes(a.unwrap(), b.unwrap()) ).equalTypes(a.unwrap(), b.unwrap())
fun ClassicTypeCheckerContext.equalTypes(a: UnwrappedType, b: UnwrappedType): Boolean { fun ClassicTypeCheckerState.equalTypes(a: UnwrappedType, b: UnwrappedType): Boolean {
return AbstractTypeChecker.equalTypes(this as AbstractTypeCheckerContext, a, b) return AbstractTypeChecker.equalTypes(this as TypeCheckerState, a, b)
} }
fun ClassicTypeCheckerContext.isSubtypeOf(subType: UnwrappedType, superType: UnwrappedType): Boolean { fun ClassicTypeCheckerState.isSubtypeOf(subType: UnwrappedType, superType: UnwrappedType): Boolean {
return AbstractTypeChecker.isSubtypeOf(this as AbstractTypeCheckerContext, subType, superType) return AbstractTypeChecker.isSubtypeOf(this as TypeCheckerState, subType, superType)
} }
} }
@@ -99,18 +95,18 @@ object NullabilityChecker {
fun isSubtypeOfAny(type: UnwrappedType): Boolean = fun isSubtypeOfAny(type: UnwrappedType): Boolean =
SimpleClassicTypeSystemContext SimpleClassicTypeSystemContext
.newBaseTypeCheckerContext(errorTypesEqualToAnything = false, stubTypesEqualToAnything = true) .newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = true)
.hasNotNullSupertype(type.lowerIfFlexible(), SupertypesPolicy.LowerIfFlexible) .hasNotNullSupertype(type.lowerIfFlexible(), SupertypesPolicy.LowerIfFlexible)
} }
fun UnwrappedType.hasSupertypeWithGivenTypeConstructor(typeConstructor: TypeConstructor) = fun UnwrappedType.hasSupertypeWithGivenTypeConstructor(typeConstructor: TypeConstructor) =
ClassicTypeCheckerContext(false).anySupertype(lowerIfFlexible(), { ClassicTypeCheckerState(false).anySupertype(lowerIfFlexible(), {
require(it is SimpleType) require(it is SimpleType)
it.constructor == typeConstructor it.constructor == typeConstructor
}, { SupertypesPolicy.LowerIfFlexible }) }, { SupertypesPolicy.LowerIfFlexible })
fun UnwrappedType.anySuperTypeConstructor(predicate: (TypeConstructor) -> Boolean) = fun UnwrappedType.anySuperTypeConstructor(predicate: (TypeConstructor) -> Boolean) =
ClassicTypeCheckerContext(false).anySupertype(lowerIfFlexible(), { ClassicTypeCheckerState(false).anySupertype(lowerIfFlexible(), {
require(it is SimpleType) require(it is SimpleType)
predicate(it.constructor) predicate(it.constructor)
}, { SupertypesPolicy.LowerIfFlexible }) }, { SupertypesPolicy.LowerIfFlexible })
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.idea.frontend.api.KtStarProjectionTypeArgument import org.jetbrains.kotlin.idea.frontend.api.KtStarProjectionTypeArgument
import org.jetbrains.kotlin.idea.frontend.api.KtTypeArgument import org.jetbrains.kotlin.idea.frontend.api.KtTypeArgument
import org.jetbrains.kotlin.idea.frontend.api.KtTypeArgumentWithVariance import org.jetbrains.kotlin.idea.frontend.api.KtTypeArgumentWithVariance
import org.jetbrains.kotlin.fir.types.ConeTypeCheckerContext import org.jetbrains.kotlin.fir.types.ConeTypeCheckerState
import org.jetbrains.kotlin.idea.frontend.api.diagnostics.KtDiagnosticWithPsi import org.jetbrains.kotlin.idea.frontend.api.diagnostics.KtDiagnosticWithPsi
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.fir.diagnostics.KT_DIAGNOSTIC_CONVERTER import org.jetbrains.kotlin.idea.frontend.api.fir.diagnostics.KT_DIAGNOSTIC_CONVERTER
@@ -62,7 +62,7 @@ internal interface KtFirAnalysisSessionComponent {
} }
} }
fun createTypeCheckerContext() = ConeTypeCheckerContext( fun createTypeCheckerContext() = ConeTypeCheckerState(
isErrorTypeEqualsToAnything = true, isErrorTypeEqualsToAnything = true,
isStubTypeEqualsToAnything = true, isStubTypeEqualsToAnything = true,
analysisSession.firResolveState.rootModuleSession.typeContext //TODO use correct session here analysisSession.firResolveState.rootModuleSession.typeContext //TODO use correct session here
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.types.KtFirType
import org.jetbrains.kotlin.idea.frontend.api.types.KtType import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
internal class KtFirSubtypingComponent( internal class KtFirSubtypingComponent(
override val analysisSession: KtFirAnalysisSession, override val analysisSession: KtFirAnalysisSession,
@@ -24,7 +23,7 @@ internal class KtFirSubtypingComponent(
check(first is KtFirType) check(first is KtFirType)
check(second is KtFirType) check(second is KtFirType)
return AbstractTypeChecker.equalTypes( return AbstractTypeChecker.equalTypes(
createTypeCheckerContext() as AbstractTypeCheckerContext, createTypeCheckerContext(),
first.coneType, first.coneType,
second.coneType second.coneType
) )
@@ -35,7 +34,7 @@ internal class KtFirSubtypingComponent(
check(subType is KtFirType) check(subType is KtFirType)
check(superType is KtFirType) check(superType is KtFirType)
return AbstractTypeChecker.isSubtypeOf( return AbstractTypeChecker.isSubtypeOf(
createTypeCheckerContext() as AbstractTypeCheckerContext, createTypeCheckerContext(),
subType.coneType, subType.coneType,
superType.coneType superType.coneType
) )