Remove all type system-specific inheritors of TypeCheckerState

This commit is contained in:
Dmitriy Novozhilov
2021-08-25 14:20:08 +03:00
parent 3f6738c8bc
commit 7e6e0a3dd6
22 changed files with 193 additions and 173 deletions
@@ -6,18 +6,20 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.impl.deduplicating
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.declarations.utils.isAbstract
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
import org.jetbrains.kotlin.fir.declarations.utils.isSuspend
import org.jetbrains.kotlin.fir.isSubstitutionOverride
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenMembers
@@ -25,12 +27,13 @@ import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenProperties
import org.jetbrains.kotlin.fir.scopes.impl.delegatedWrapperData
import org.jetbrains.kotlin.fir.scopes.impl.toConeType
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeTypeCheckerState
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.utils.addIfNotNull
object FirImplementationMismatchChecker : FirClassChecker() {
@@ -66,7 +69,7 @@ object FirImplementationMismatchChecker : FirClassChecker() {
containingClass: FirClass,
context: CheckerContext,
reporter: DiagnosticReporter,
typeCheckerState: ConeTypeCheckerState,
typeCheckerState: TypeCheckerState,
symbol: FirCallableSymbol<*>,
classScope: FirTypeScope
) {
@@ -8,19 +8,22 @@ package org.jetbrains.kotlin.fir.types
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.fir.diagnostics.ConeIntermediateDiagnostic
import org.jetbrains.kotlin.fir.isPrimitiveNumberOrUnsignedNumberType
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.calls.NoSubstitutor
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.createTypeSubstitutorByTypeConstructor
import org.jetbrains.kotlin.fir.resolve.symbolProvider
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.AbstractTypeRefiner
import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.model.*
import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.addToStdlib.cast
@@ -109,8 +112,14 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
override fun newTypeCheckerState(
errorTypesEqualToAnything: Boolean,
stubTypesEqualToAnything: Boolean
): ConeTypeCheckerState =
ConeTypeCheckerState(errorTypesEqualToAnything, stubTypesEqualToAnything, this)
): TypeCheckerState = TypeCheckerState(
errorTypesEqualToAnything,
stubTypesEqualToAnything,
allowedTypeVariable = true,
typeSystemContext = this,
kotlinTypePreparator = ConeTypePreparator(session),
kotlinTypeRefiner = AbstractTypeRefiner.Default
)
override fun KotlinTypeMarker.canHaveUndefinedNullability(): Boolean {
require(this is ConeKotlinType)
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.types.AbstractTypeRefiner
import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.TypeCheckerState.SupertypesPolicy.DoCustomTransform
import org.jetbrains.kotlin.types.TypeCheckerState.SupertypesPolicy.LowerIfFlexible
@@ -599,19 +598,3 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
return this is ConeTypeVariableType
}
}
class ConeTypeCheckerState(
override val isErrorTypeEqualsToAnything: Boolean,
override val isStubTypeEqualsToAnything: Boolean,
override val typeSystemContext: ConeInferenceContext,
override val kotlinTypePreparator: ConeTypePreparator = ConeTypePreparator(typeSystemContext.session),
) : TypeCheckerState() {
override val kotlinTypeRefiner: AbstractTypeRefiner
get() = AbstractTypeRefiner.Default
val session: FirSession = typeSystemContext.session
override val allowedTypeVariable: Boolean
get() = true
}
@@ -29,13 +29,14 @@ class FirCorrespondingSupertypesCache(private val session: FirSession) : FirSess
): List<ConeClassLikeType>? {
if (type !is ConeClassLikeType || supertypeConstructor !is ConeClassLikeLookupTag) return null
val typeCheckerState = session.typeContext.newTypeCheckerState(
val typeContext = session.typeContext
val typeCheckerState = typeContext.newTypeCheckerState(
errorTypesEqualToAnything = false,
stubTypesEqualToAnything = true
)
val lookupTag = type.lookupTag
if (lookupTag == supertypeConstructor) return listOf(captureType(type, typeCheckerState.typeSystemContext))
if (lookupTag == supertypeConstructor) return listOf(captureType(type, typeContext))
if (lookupTag !in cache) {
cache[lookupTag] = computeSupertypesMap(lookupTag, typeCheckerState)
}
@@ -43,8 +44,8 @@ class FirCorrespondingSupertypesCache(private val session: FirSession) : FirSess
val resultTypes = cache[lookupTag]?.getOrDefault(supertypeConstructor, emptyList()) ?: return null
if (type.typeArguments.isEmpty()) return resultTypes
val capturedType = captureType(type, typeCheckerState.typeSystemContext)
val substitutionSupertypePolicy = typeCheckerState.typeSystemContext.substitutionSupertypePolicy(capturedType)
val capturedType = captureType(type, typeContext)
val substitutionSupertypePolicy = typeContext.substitutionSupertypePolicy(capturedType)
return resultTypes.map {
substitutionSupertypePolicy.transformType(typeCheckerState, it) as ConeClassLikeType
}
@@ -55,7 +56,7 @@ class FirCorrespondingSupertypesCache(private val session: FirSession) : FirSess
private fun computeSupertypesMap(
subtypeLookupTag: ConeClassLikeLookupTag,
state: ConeTypeCheckerState
state: TypeCheckerState
): Map<ConeClassLikeLookupTag, List<ConeClassLikeType>>? {
val resultingMap = HashMap<ConeClassLikeLookupTag, List<ConeClassLikeType>>()
@@ -84,7 +85,7 @@ class FirCorrespondingSupertypesCache(private val session: FirSession) : FirSess
private fun computeSupertypePolicyAndPutInMap(
supertype: SimpleTypeMarker,
resultingMap: MutableMap<ConeClassLikeLookupTag, List<ConeClassLikeType>>,
state: ConeTypeCheckerState
state: TypeCheckerState
): TypeCheckerState.SupertypesPolicy {
val supertypeLookupTag = (supertype as ConeClassLikeType).lookupTag
val captured =
@@ -164,7 +164,8 @@ class JavaNullabilityChecker(val upperBoundChecker: UpperBoundChecker) : Additio
var metWrongNullabilityInsideArguments = false
val typeState: TypeCheckerState = object : ClassicTypeCheckerState(errorTypeEqualsToAnything = true) {
@OptIn(ClassicTypeCheckerStateInternals::class)
val typeState: TypeCheckerState = object : ClassicTypeCheckerState(isErrorTypeEqualsToAnything = true) {
private var expectsTypeArgument = false
override fun customIsSubtypeOf(subType: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean {
@@ -194,7 +195,7 @@ class JavaNullabilityChecker(val upperBoundChecker: UpperBoundChecker) : Additio
): Boolean {
if (superType !is NotNullTypeVariable) return false
return !AbstractNullabilityChecker.isSubtypeOfAny(
ClassicTypeCheckerState(errorTypeEqualsToAnything = true) as TypeCheckerState,
createClassicTypeCheckerState(isErrorTypeEqualsToAnything = true),
subType
)
}
@@ -37,12 +37,12 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE
import org.jetbrains.kotlin.types.checker.ClassicTypeCheckerState
import org.jetbrains.kotlin.types.checker.ClassicTypeCheckerStateInternals
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
import org.jetbrains.kotlin.types.expressions.KotlinTypeInfo
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.TypeRefinement
import org.jetbrains.kotlin.types.typeUtil.*
import javax.inject.Inject
@@ -252,10 +252,10 @@ class BuilderInferenceSupport(
}
}
@OptIn(ClassicTypeCheckerStateInternals::class)
private class BuilderInferenceTypeCheckerState(
private val allowOnlyTrivialConstraints: Boolean
) : ClassicTypeCheckerState(errorTypeEqualsToAnything = true) {
) : ClassicTypeCheckerState(isErrorTypeEqualsToAnything = true) {
override fun addSubtypeConstraint(subType: KotlinTypeMarker, superType: KotlinTypeMarker, isFromNullabilityConstraint: Boolean): Boolean? {
require(subType is UnwrappedType)
require(superType is UnwrappedType)
@@ -229,7 +229,7 @@ internal class CollectionStubMethodLowering(val context: JvmBackendContext) : Cl
}
private fun createTypeCheckerState(overrideFun: IrSimpleFunction, parentFun: IrSimpleFunction): TypeCheckerState =
IrTypeCheckerState(
createIrTypeCheckerState(
IrTypeSystemContextWithAdditionalAxioms(
context.typeSystem,
overrideFun.typeParameters,
@@ -438,14 +438,14 @@ class IrOverridingUtil(
return if (a == null || b == null) true else isVisibilityMoreSpecific(a, b)
}
private fun IrTypeCheckerState.isSubtypeOf(a: IrType, b: IrType) =
AbstractTypeChecker.isSubtypeOf(this as TypeCheckerState, a, b)
private fun TypeCheckerState.isSubtypeOf(a: IrType, b: IrType) =
AbstractTypeChecker.isSubtypeOf(this, a, b)
private fun IrTypeCheckerState.equalTypes(a: IrType, b: IrType) =
AbstractTypeChecker.equalTypes(this as TypeCheckerState, a, b)
private fun TypeCheckerState.equalTypes(a: IrType, b: IrType) =
AbstractTypeChecker.equalTypes(this, a, b)
private fun createTypeCheckerState(a: List<IrTypeParameter>, b: List<IrTypeParameter>) =
IrTypeCheckerState(IrTypeSystemContextWithAdditionalAxioms(typeSystem, a, b))
private fun createTypeCheckerState(a: List<IrTypeParameter>, b: List<IrTypeParameter>): TypeCheckerState =
createIrTypeCheckerState(IrTypeSystemContextWithAdditionalAxioms(typeSystem, a, b))
private fun isReturnTypeMoreSpecific(
a: IrOverridableMember,
@@ -453,8 +453,8 @@ class IrOverridingUtil(
b: IrOverridableMember,
bReturnType: IrType
): Boolean {
val typeCheckerContext = createTypeCheckerState(a.typeParameters, b.typeParameters)
return typeCheckerContext.isSubtypeOf(aReturnType, bReturnType)
val typeCheckerState = createTypeCheckerState(a.typeParameters, b.typeParameters)
return typeCheckerState.isSubtypeOf(aReturnType, bReturnType)
}
private fun isMoreSpecific(
@@ -674,7 +674,7 @@ class IrOverridingUtil(
}
val typeCheckerState =
IrTypeCheckerState(
createIrTypeCheckerState(
IrTypeSystemContextWithAdditionalAxioms(
typeSystem,
superTypeParameters,
@@ -697,7 +697,7 @@ class IrOverridingUtil(
superValueParameters.forEachIndexed { index, parameter ->
if (!AbstractTypeChecker.equalTypes(
typeCheckerState as TypeCheckerState,
typeCheckerState,
subValueParameters[index].type,
parameter.type
)
@@ -710,7 +710,7 @@ class IrOverridingUtil(
if (checkReturnType) {
if (!AbstractTypeChecker.isSubtypeOf(
typeCheckerState as TypeCheckerState,
typeCheckerState,
subMember.returnType,
superMember.returnType
)
@@ -5,26 +5,17 @@
package org.jetbrains.kotlin.ir.types
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.types.AbstractTypePreparator
import org.jetbrains.kotlin.types.AbstractTypeRefiner
import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
open class IrTypeCheckerState(override val typeSystemContext: IrTypeSystemContext): TypeCheckerState() {
override val kotlinTypePreparator: AbstractTypePreparator
get() = AbstractTypePreparator.Default
override val kotlinTypeRefiner: AbstractTypeRefiner
get() = AbstractTypeRefiner.Default
val irBuiltIns: IrBuiltIns get() = typeSystemContext.irBuiltIns
override val isErrorTypeEqualsToAnything get() = false
override val isStubTypeEqualsToAnything get() = false
override val allowedTypeVariable: Boolean
get() = false
fun createIrTypeCheckerState(typeSystemContext: IrTypeSystemContext): TypeCheckerState {
return TypeCheckerState(
isErrorTypeEqualsToAnything = false,
isStubTypeEqualsToAnything = false,
allowedTypeVariable = false,
typeSystemContext = typeSystemContext,
kotlinTypePreparator = AbstractTypePreparator.Default,
kotlinTypeRefiner = AbstractTypeRefiner.Default
)
}
@@ -504,7 +504,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
override fun newTypeCheckerState(
errorTypesEqualToAnything: Boolean,
stubTypesEqualToAnything: Boolean
): TypeCheckerState = IrTypeCheckerState(this)
): TypeCheckerState = createIrTypeCheckerState(this)
override fun KotlinTypeMarker.isUninferredParameter(): Boolean = false
override fun KotlinTypeMarker.withNullability(nullable: Boolean): KotlinTypeMarker {
@@ -30,7 +30,7 @@ fun IrType.isSubtypeOfClass(superClass: IrClassSymbol): Boolean =
this is IrSimpleType && classifier.isSubtypeOfClass(superClass)
fun IrType.isSubtypeOf(superType: IrType, typeSystem: IrTypeSystemContext): Boolean =
AbstractTypeChecker.isSubtypeOf(IrTypeCheckerState(typeSystem), this, superType)
AbstractTypeChecker.isSubtypeOf(createIrTypeCheckerState(typeSystem), this, superType)
fun IrType.isNullable(): Boolean =
when (this) {
@@ -10,7 +10,10 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
import org.jetbrains.kotlin.resolve.calls.inference.model.*
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind.*
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.AbstractTypeApproximator
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.model.*
import org.jetbrains.kotlin.utils.SmartList
import kotlin.math.max
@@ -214,13 +217,20 @@ class ConstraintInjector(
private fun Context.isAllowedType(type: KotlinTypeMarker) =
type.typeDepth() <= maxTypeDepthFromInitialConstraints + ALLOWED_DEPTH_DELTA_FOR_INCORPORATION
private inner class TypeCheckerStateForConstraintInjector(val c: Context, val position: IncorporationConstraintPosition) :
TypeCheckerStateForConstraintSystem(c), ConstraintIncorporator.Context, TypeSystemInferenceExtensionContext by c {
override val kotlinTypePreparator: AbstractTypePreparator
get() = baseState.kotlinTypePreparator
override val kotlinTypeRefiner: AbstractTypeRefiner
get() = baseState.kotlinTypeRefiner
private inner class TypeCheckerStateForConstraintInjector(
baseState: TypeCheckerState,
val c: Context,
val position: IncorporationConstraintPosition
) : TypeCheckerStateForConstraintSystem(
c,
baseState.kotlinTypePreparator,
baseState.kotlinTypeRefiner
), ConstraintIncorporator.Context, TypeSystemInferenceExtensionContext by c {
constructor(c: Context, position: IncorporationConstraintPosition) : this(
c.newTypeCheckerState(errorTypesEqualToAnything = true, stubTypesEqualToAnything = true),
c,
position
)
// We use `var` intentionally to avoid extra allocations as this property is quite "hot"
private var possibleNewConstraints: MutableList<Pair<TypeVariableMarker, Constraint>>? = null
@@ -248,8 +258,6 @@ class ConstraintInjector(
baseUpperType = upperType
}
val baseState: TypeCheckerState = newTypeCheckerState(isErrorTypeEqualsToAnything, isStubTypeEqualsToAnything)
fun runIsSubtypeOf(
lowerType: KotlinTypeMarker,
upperType: KotlinTypeMarker,
@@ -5,23 +5,21 @@
package org.jetbrains.kotlin.resolve.calls.inference.components
import org.jetbrains.kotlin.types.AbstractNullabilityChecker
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.model.*
abstract class TypeCheckerStateForConstraintSystem(override val typeSystemContext: TypeSystemInferenceExtensionContext) :
TypeCheckerState() {
override val allowedTypeVariable: Boolean
get() = false
override val isErrorTypeEqualsToAnything: Boolean
get() = true
override val isStubTypeEqualsToAnything: Boolean
get() = true
abstract class TypeCheckerStateForConstraintSystem(
val extensionTypeContext: TypeSystemInferenceExtensionContext,
kotlinTypePreparator: AbstractTypePreparator,
kotlinTypeRefiner: AbstractTypeRefiner
) : TypeCheckerState(
isErrorTypeEqualsToAnything = true,
isStubTypeEqualsToAnything = true,
allowedTypeVariable = false,
typeSystemContext = extensionTypeContext,
kotlinTypePreparator,
kotlinTypeRefiner
) {
abstract val isInferenceCompatibilityEnabled: Boolean
abstract fun isMyTypeVariable(type: SimpleTypeMarker): Boolean
@@ -38,7 +36,7 @@ abstract class TypeCheckerStateForConstraintSystem(override val typeSystemContex
abstract fun addEqualityConstraint(typeVariable: TypeConstructorMarker, type: KotlinTypeMarker)
override fun getLowerCapturedTypePolicy(subType: SimpleTypeMarker, superType: CapturedTypeMarker): LowerCapturedTypePolicy =
with(typeSystemContext) {
with(extensionTypeContext) {
return when {
isMyTypeVariable(subType) -> {
val projection = superType.typeConstructorProjection()
@@ -73,10 +71,10 @@ abstract class TypeCheckerStateForConstraintSystem(override val typeSystemContex
// we should strip annotation's because we have incorporation operation and they should be not affected
val mySubType =
if (hasExact) extractTypeForProjectedType(subType, out = true)
?: with(typeSystemContext) { subType.removeExactAnnotation() } else subType
?: with(extensionTypeContext) { subType.removeExactAnnotation() } else subType
val mySuperType =
if (hasExact) extractTypeForProjectedType(superType, out = false)
?: with(typeSystemContext) { superType.removeExactAnnotation() } else superType
?: with(extensionTypeContext) { superType.removeExactAnnotation() } else superType
val result = internalAddSubtypeConstraint(mySubType, mySuperType, isFromNullabilityConstraint)
if (!hasExact) return result
@@ -87,7 +85,7 @@ abstract class TypeCheckerStateForConstraintSystem(override val typeSystemContex
return (result ?: true) && (result2 ?: true)
}
private fun extractTypeForProjectedType(type: KotlinTypeMarker, out: Boolean): KotlinTypeMarker? = with(typeSystemContext) {
private fun extractTypeForProjectedType(type: KotlinTypeMarker, out: Boolean): KotlinTypeMarker? = with(extensionTypeContext) {
val typeMarker = type.asSimpleType()?.asCapturedType() ?: return null
val projection = typeMarker.typeConstructorProjection()
@@ -99,10 +97,10 @@ abstract class TypeCheckerStateForConstraintSystem(override val typeSystemContex
}
private fun KotlinTypeMarker.isTypeVariableWithExact() =
with(typeSystemContext) { hasExactAnnotation() } && anyBound(this@TypeCheckerStateForConstraintSystem::isMyTypeVariable)
with(extensionTypeContext) { hasExactAnnotation() } && anyBound(this@TypeCheckerStateForConstraintSystem::isMyTypeVariable)
private fun KotlinTypeMarker.isTypeVariableWithNoInfer() =
with(typeSystemContext) { hasNoInferAnnotation() } && anyBound(this@TypeCheckerStateForConstraintSystem::isMyTypeVariable)
with(extensionTypeContext) { hasNoInferAnnotation() } && anyBound(this@TypeCheckerStateForConstraintSystem::isMyTypeVariable)
private fun internalAddSubtypeConstraint(
subType: KotlinTypeMarker,
@@ -130,7 +128,7 @@ abstract class TypeCheckerStateForConstraintSystem(override val typeSystemContex
// extract type variable only from type like Captured(out T)
private fun extractTypeVariableForSubtype(subType: KotlinTypeMarker, superType: KotlinTypeMarker): KotlinTypeMarker? =
with(typeSystemContext) {
with(extensionTypeContext) {
val typeMarker = subType.asSimpleType()?.asCapturedType() ?: return null
@@ -198,7 +196,7 @@ abstract class TypeCheckerStateForConstraintSystem(override val typeSystemContex
typeVariable: KotlinTypeMarker,
subType: KotlinTypeMarker,
isFromNullabilityConstraint: Boolean = false
): Boolean = with(typeSystemContext) {
): Boolean = with(extensionTypeContext) {
val lowerConstraint = when (typeVariable) {
is SimpleTypeMarker ->
/*
@@ -265,7 +263,7 @@ abstract class TypeCheckerStateForConstraintSystem(override val typeSystemContex
* T? <: Foo <=> T <: Foo && Nothing? <: Foo
* T <: Foo -- leave as is
*/
private fun simplifyUpperConstraint(typeVariable: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean = with(typeSystemContext) {
private fun simplifyUpperConstraint(typeVariable: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean = with(extensionTypeContext) {
val typeVariableLowerBound = typeVariable.lowerBoundIfFlexible()
val simplifiedSuperType = if (typeVariableLowerBound.isDefinitelyNotNullType()) {
superType.withNullability(true)
@@ -285,7 +283,7 @@ abstract class TypeCheckerStateForConstraintSystem(override val typeSystemContex
}
private fun simplifyConstraintForPossibleIntersectionSubType(subType: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean? =
with(typeSystemContext) {
with(extensionTypeContext) {
@Suppress("NAME_SHADOWING")
val subType = subType.lowerBoundIfFlexible()
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.resolve.multiplatform
import org.jetbrains.kotlin.types.KotlinTypeRefinerImpl
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
@@ -20,7 +19,6 @@ import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.*
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
import org.jetbrains.kotlin.types.TypeRefinement
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.kotlin.utils.keysToMap
@@ -305,8 +303,8 @@ object ExpectedActualResolver {
kotlinTypeRefiner: KotlinTypeRefiner,
): Boolean {
with(NewKotlinTypeCheckerImpl(kotlinTypeRefiner)) {
return ClassicTypeCheckerState(
errorTypeEqualsToAnything = false,
return createClassicTypeCheckerState(
isErrorTypeEqualsToAnything = false,
typeSystemContext = typeSystemContext,
kotlinTypeRefiner = kotlinTypeRefiner,
).equalTypes(a.unwrap(), b.unwrap())
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.types.AbstractNullabilityChecker
import org.jetbrains.kotlin.types.KotlinTypeFactory
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.TypeIntersector
import org.jetbrains.kotlin.types.checker.ClassicTypeCheckerState
import org.jetbrains.kotlin.types.checker.createClassicTypeCheckerState
class SlowTypeAssertionsEnabledTest : KotlinTestWithEnvironmentManagement() {
@@ -45,7 +45,7 @@ class SlowTypeAssertionsEnabledTest : KotlinTestWithEnvironmentManagement() {
try {
val superType = TypeIntersector.intersectTypes(listOf(builtIns.charSequence.defaultType, builtIns.comparable.defaultType))
AbstractNullabilityChecker.isPossibleSubtype(
ClassicTypeCheckerState(errorTypeEqualsToAnything = true), builtIns.annotationType,
createClassicTypeCheckerState(isErrorTypeEqualsToAnything = true), builtIns.annotationType,
superType as SimpleType
)
} catch (e: AssertionError) {
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.types
import org.jetbrains.kotlin.descriptors.containerRelation
import org.jetbrains.kotlin.types.TypeCheckerState.LowerCapturedTypePolicy.*
import org.jetbrains.kotlin.types.TypeCheckerState.SupertypesPolicy
import org.jetbrains.kotlin.types.model.*
@@ -22,14 +21,14 @@ import java.util.*
* Once some type-checker operation is performed using a [TypeCheckerProviderContext], for example a [AbstractTypeChecker.isSubtypeOf],
* new instance of particular [TypeCheckerState] should be created, with properly specified type system context
*/
abstract class TypeCheckerState {
abstract val kotlinTypePreparator: AbstractTypePreparator
abstract val kotlinTypeRefiner: AbstractTypeRefiner
abstract val typeSystemContext: TypeSystemContext
abstract val allowedTypeVariable: Boolean
open class TypeCheckerState(
val isErrorTypeEqualsToAnything: Boolean,
val isStubTypeEqualsToAnything: Boolean,
val allowedTypeVariable: Boolean,
val typeSystemContext: TypeSystemContext,
val kotlinTypePreparator: AbstractTypePreparator,
val kotlinTypeRefiner: AbstractTypeRefiner
) {
@OptIn(TypeRefinement::class)
fun refineType(type: KotlinTypeMarker): KotlinTypeMarker {
return kotlinTypeRefiner.refineType(type)
@@ -41,10 +40,6 @@ abstract class TypeCheckerState {
open fun customIsSubtypeOf(subType: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean = true
abstract val isErrorTypeEqualsToAnything: Boolean
abstract val isStubTypeEqualsToAnything: Boolean
protected var argumentsDepth = 0
internal inline fun <T> runWithArgumentsSettings(subArgument: KotlinTypeMarker, f: TypeCheckerState.() -> T): T {
@@ -32,7 +32,10 @@ import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.types.*;
import org.jetbrains.kotlin.types.checker.*;
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
import org.jetbrains.kotlin.types.checker.KotlinTypePreparator;
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner;
import org.jetbrains.kotlin.types.checker.NewKotlinTypeCheckerImpl;
import org.jetbrains.kotlin.utils.SmartSet;
import java.util.*;
@@ -308,7 +311,7 @@ public class OverridingUtil {
return OverrideCompatibilityInfo.conflict("Type parameter number mismatch");
}
Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerState> typeChecker = createTypeChecker(superTypeParameters, subTypeParameters);
Pair<NewKotlinTypeCheckerImpl, TypeCheckerState> typeChecker = createTypeChecker(superTypeParameters, subTypeParameters);
for (int i = 0; i < superTypeParameters.size(); i++) {
if (!areTypeParametersEquivalent(
@@ -384,7 +387,7 @@ public class OverridingUtil {
}
@NotNull
private Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerState> createTypeChecker(
private Pair<NewKotlinTypeCheckerImpl, TypeCheckerState> createTypeChecker(
@NotNull List<TypeParameterDescriptor> firstParameters,
@NotNull List<TypeParameterDescriptor> secondParameters
) {
@@ -392,18 +395,18 @@ public class OverridingUtil {
"Should be the same number of type parameters: " + firstParameters + " vs " + secondParameters;
NewKotlinTypeCheckerImpl typeChecker = new NewKotlinTypeCheckerImpl(kotlinTypeRefiner, KotlinTypePreparator.Default.INSTANCE);
ClassicTypeCheckerState context = createTypeCheckerContext(firstParameters, secondParameters);
TypeCheckerState state = createTypeCheckerState(firstParameters, secondParameters);
return new Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerState>(typeChecker, context);
return new Pair<NewKotlinTypeCheckerImpl, TypeCheckerState>(typeChecker, state);
}
@NotNull
private ClassicTypeCheckerState createTypeCheckerContext(
private TypeCheckerState createTypeCheckerState(
@NotNull List<TypeParameterDescriptor> firstParameters,
@NotNull List<TypeParameterDescriptor> secondParameters
) {
if (firstParameters.isEmpty()) {
return (ClassicTypeCheckerState) new OverridingUtilTypeSystemContext(null, equalityAxioms, kotlinTypeRefiner)
return new OverridingUtilTypeSystemContext(null, equalityAxioms, kotlinTypeRefiner)
.newTypeCheckerState(true, true);
}
@@ -412,7 +415,7 @@ public class OverridingUtil {
matchingTypeConstructors.put(firstParameters.get(i).getTypeConstructor(), secondParameters.get(i).getTypeConstructor());
}
return (ClassicTypeCheckerState) new OverridingUtilTypeSystemContext(matchingTypeConstructors, equalityAxioms, kotlinTypeRefiner)
return new OverridingUtilTypeSystemContext(matchingTypeConstructors, equalityAxioms, kotlinTypeRefiner)
.newTypeCheckerState(true, true);
}
@@ -435,7 +438,7 @@ public class OverridingUtil {
private boolean areTypesEquivalent(
@NotNull KotlinType typeInSuper,
@NotNull KotlinType typeInSub,
@NotNull Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerState> typeChecker
@NotNull Pair<NewKotlinTypeCheckerImpl, TypeCheckerState> typeChecker
) {
boolean bothErrors = KotlinTypeKt.isError(typeInSuper) && KotlinTypeKt.isError(typeInSub);
if (bothErrors) return true;
@@ -446,7 +449,7 @@ public class OverridingUtil {
private boolean areTypeParametersEquivalent(
@NotNull TypeParameterDescriptor superTypeParameter,
@NotNull TypeParameterDescriptor subTypeParameter,
@NotNull Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerState> typeChecker
@NotNull Pair<NewKotlinTypeCheckerImpl, TypeCheckerState> typeChecker
) {
List<KotlinType> superBounds = superTypeParameter.getUpperBounds();
List<KotlinType> subBounds = new ArrayList<KotlinType>(subTypeParameter.getUpperBounds());
@@ -584,7 +587,7 @@ public class OverridingUtil {
if (!isVisibilityMoreSpecific(a, b)) return false;
Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerState> checker =
Pair<NewKotlinTypeCheckerImpl, TypeCheckerState> checker =
DEFAULT.createTypeChecker(a.getTypeParameters(), b.getTypeParameters());
if (a instanceof FunctionDescriptor) {
@@ -641,7 +644,7 @@ public class OverridingUtil {
@NotNull KotlinType aReturnType,
@NotNull CallableDescriptor b,
@NotNull KotlinType bReturnType,
@NotNull Pair<NewKotlinTypeCheckerImpl, ClassicTypeCheckerState> typeChecker
@NotNull Pair<NewKotlinTypeCheckerImpl, TypeCheckerState> typeChecker
) {
return typeChecker.getFirst().isSubtypeOf(typeChecker.getSecond(), aReturnType.unwrap(), bReturnType.unwrap());
}
@@ -7,10 +7,10 @@ package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.TypeConstructor
import org.jetbrains.kotlin.types.checker.ClassicTypeCheckerState
import org.jetbrains.kotlin.types.checker.ClassicTypeSystemContext
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
import org.jetbrains.kotlin.types.checker.createClassicTypeCheckerState
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
class OverridingUtilTypeSystemContext(
@@ -29,11 +29,11 @@ class OverridingUtilTypeSystemContext(
errorTypesEqualToAnything: Boolean,
stubTypesEqualToAnything: Boolean
): TypeCheckerState {
return ClassicTypeCheckerState(
return createClassicTypeCheckerState(
errorTypesEqualToAnything,
stubTypesEqualToAnything,
kotlinTypeRefiner,
typeSystemContext = this
typeSystemContext = this,
kotlinTypeRefiner = kotlinTypeRefiner
)
}
@@ -16,23 +16,48 @@
package org.jetbrains.kotlin.types.checker
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
import org.jetbrains.kotlin.types.TypeCheckerState
@RequiresOptIn
annotation class ClassicTypeCheckerStateInternals
/**
* Class [ClassicTypeCheckerState] exists only to provide default arguments for
* cases when someone need to implement custom [TypeCheckerState] using default
* arguments. If you need to create only an instance of [TypeCheckerState] please
* use [createClassicTypeCheckerState] method.
*
* Also please don't use [ClassicTypeCheckerState] explicitly (except for inheritance)
*/
@ClassicTypeCheckerStateInternals
open class ClassicTypeCheckerState(
val errorTypeEqualsToAnything: Boolean,
val stubTypeEqualsToAnything: Boolean = true,
override val kotlinTypeRefiner: KotlinTypeRefiner = KotlinTypeRefiner.Default,
override val kotlinTypePreparator: KotlinTypePreparator = KotlinTypePreparator.Default,
override val typeSystemContext: ClassicTypeSystemContext = SimpleClassicTypeSystemContext
) : TypeCheckerState() {
override val isErrorTypeEqualsToAnything: Boolean
get() = errorTypeEqualsToAnything
isErrorTypeEqualsToAnything: Boolean,
isStubTypeEqualsToAnything: Boolean = true,
typeSystemContext: ClassicTypeSystemContext = SimpleClassicTypeSystemContext,
kotlinTypePreparator: KotlinTypePreparator = KotlinTypePreparator.Default,
kotlinTypeRefiner: KotlinTypeRefiner = KotlinTypeRefiner.Default
) : TypeCheckerState(
isErrorTypeEqualsToAnything,
isStubTypeEqualsToAnything,
allowedTypeVariable = true,
typeSystemContext,
kotlinTypePreparator,
kotlinTypeRefiner
)
override val isStubTypeEqualsToAnything: Boolean
get() = stubTypeEqualsToAnything
override val allowedTypeVariable: Boolean
get() = true
fun createClassicTypeCheckerState(
isErrorTypeEqualsToAnything: Boolean,
isStubTypeEqualsToAnything: Boolean = true,
typeSystemContext: ClassicTypeSystemContext = SimpleClassicTypeSystemContext,
kotlinTypePreparator: KotlinTypePreparator = KotlinTypePreparator.Default,
kotlinTypeRefiner: KotlinTypeRefiner = KotlinTypeRefiner.Default
): TypeCheckerState {
return TypeCheckerState(
isErrorTypeEqualsToAnything,
isStubTypeEqualsToAnything,
allowedTypeVariable = true,
typeSystemContext,
kotlinTypePreparator,
kotlinTypeRefiner
)
}
@@ -392,7 +392,7 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
errorTypesEqualToAnything: Boolean,
stubTypesEqualToAnything: Boolean
): TypeCheckerState {
return ClassicTypeCheckerState(errorTypesEqualToAnything, stubTypesEqualToAnything, typeSystemContext = this)
return createClassicTypeCheckerState(errorTypesEqualToAnything, stubTypesEqualToAnything, typeSystemContext = this)
}
override fun nullableNothingType(): SimpleTypeMarker {
@@ -411,7 +411,7 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
return builtIns.anyType
}
open val builtIns: KotlinBuiltIns
val builtIns: KotlinBuiltIns
get() = throw UnsupportedOperationException("Not supported")
override fun KotlinTypeMarker.makeDefinitelyNotNullOrNotNull(): KotlinTypeMarker {
@@ -49,10 +49,14 @@ object StrictEqualityTypeChecker {
object ErrorTypesAreEqualToAnything : KotlinTypeChecker {
override fun isSubtypeOf(subtype: KotlinType, supertype: KotlinType): Boolean =
NewKotlinTypeChecker.Default.run { ClassicTypeCheckerState(true).isSubtypeOf(subtype.unwrap(), supertype.unwrap()) }
NewKotlinTypeChecker.Default.run {
createClassicTypeCheckerState(isErrorTypeEqualsToAnything = true).isSubtypeOf(subtype.unwrap(), supertype.unwrap())
}
override fun equalTypes(a: KotlinType, b: KotlinType): Boolean =
NewKotlinTypeChecker.Default.run { ClassicTypeCheckerState(true).equalTypes(a.unwrap(), b.unwrap()) }
NewKotlinTypeChecker.Default.run {
createClassicTypeCheckerState(isErrorTypeEqualsToAnything = true).equalTypes(a.unwrap(), b.unwrap())
}
}
interface NewKotlinTypeChecker : KotlinTypeChecker {
@@ -73,26 +77,25 @@ class NewKotlinTypeCheckerImpl(
override val overridingUtil: OverridingUtil = OverridingUtil.createWithTypeRefiner(kotlinTypeRefiner)
override fun isSubtypeOf(subtype: KotlinType, supertype: KotlinType): Boolean =
ClassicTypeCheckerState(
createClassicTypeCheckerState(
true, kotlinTypeRefiner = kotlinTypeRefiner, kotlinTypePreparator = kotlinTypePreparator
).isSubtypeOf(subtype.unwrap(), supertype.unwrap()) // todo fix flag errorTypeEqualsToAnything
override fun equalTypes(a: KotlinType, b: KotlinType): Boolean =
ClassicTypeCheckerState(
createClassicTypeCheckerState(
false, kotlinTypeRefiner = kotlinTypeRefiner, kotlinTypePreparator = kotlinTypePreparator
).equalTypes(a.unwrap(), b.unwrap())
fun ClassicTypeCheckerState.equalTypes(a: UnwrappedType, b: UnwrappedType): Boolean {
return AbstractTypeChecker.equalTypes(this as TypeCheckerState, a, b)
fun TypeCheckerState.equalTypes(a: UnwrappedType, b: UnwrappedType): Boolean {
return AbstractTypeChecker.equalTypes(this, a, b)
}
fun ClassicTypeCheckerState.isSubtypeOf(subType: UnwrappedType, superType: UnwrappedType): Boolean {
return AbstractTypeChecker.isSubtypeOf(this as TypeCheckerState, subType, superType)
fun TypeCheckerState.isSubtypeOf(subType: UnwrappedType, superType: UnwrappedType): Boolean {
return AbstractTypeChecker.isSubtypeOf(this, subType, superType)
}
}
object NullabilityChecker {
fun isSubtypeOfAny(type: UnwrappedType): Boolean =
SimpleClassicTypeSystemContext
.newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = true)
@@ -100,13 +103,13 @@ object NullabilityChecker {
}
fun UnwrappedType.hasSupertypeWithGivenTypeConstructor(typeConstructor: TypeConstructor) =
ClassicTypeCheckerState(false).anySupertype(lowerIfFlexible(), {
createClassicTypeCheckerState(isErrorTypeEqualsToAnything = false).anySupertype(lowerIfFlexible(), {
require(it is SimpleType)
it.constructor == typeConstructor
}, { SupertypesPolicy.LowerIfFlexible })
fun UnwrappedType.anySuperTypeConstructor(predicate: (TypeConstructor) -> Boolean) =
ClassicTypeCheckerState(false).anySupertype(lowerIfFlexible(), {
createClassicTypeCheckerState(isErrorTypeEqualsToAnything = false).anySupertype(lowerIfFlexible(), {
require(it is SimpleType)
predicate(it.constructor)
}, { SupertypesPolicy.LowerIfFlexible })
@@ -12,16 +12,19 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.toFirDiagnostics
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.ConeInferenceContext
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeStarProjection
import org.jetbrains.kotlin.fir.types.ConeTypeProjection
import org.jetbrains.kotlin.idea.frontend.api.KtStarProjectionTypeArgument
import org.jetbrains.kotlin.idea.frontend.api.KtTypeArgument
import org.jetbrains.kotlin.idea.frontend.api.KtTypeArgumentWithVariance
import org.jetbrains.kotlin.fir.types.ConeTypeCheckerState
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.diagnostics.KT_DIAGNOSTIC_CONVERTER
import org.jetbrains.kotlin.idea.frontend.api.fir.types.KtFirType
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.model.convertVariance
internal interface KtFirAnalysisSessionComponent {
@@ -62,9 +65,8 @@ internal interface KtFirAnalysisSessionComponent {
}
}
fun createTypeCheckerContext() = ConeTypeCheckerState(
isErrorTypeEqualsToAnything = true,
isStubTypeEqualsToAnything = true,
analysisSession.firResolveState.rootModuleSession.typeContext //TODO use correct session here
)
fun createTypeCheckerContext(): TypeCheckerState {
// TODO use correct session here,
return analysisSession.firResolveState.rootModuleSession.typeContext.newTypeCheckerState(errorTypesEqualToAnything = true, stubTypesEqualToAnything = true)
}
}