From 1ceec4d6d705a6b59f49dad55440ea5031f8bde5 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 7 Nov 2023 11:03:19 +0100 Subject: [PATCH] K2: make type variable based types not class like #KT-57921 Fixed #KT-62420 Fixed --- .../evaluate/FirCompileTimeConstantEvaluator.kt | 4 +--- .../checkers/ConeTypeCompatibilityChecker.kt | 8 +++++--- .../kotlin/fir/analysis/checkers/FirHelpers.kt | 14 ++++++++------ .../fir/types/ConeTypeVariableAndStubTypes.kt | 11 ++++------- .../kotlin/fir/backend/Fir2IrTypeConverter.kt | 3 +-- .../jetbrains/kotlin/fir/resolve/LookupTagUtils.kt | 3 +-- .../fir/resolve/substitution/Substitutors.kt | 6 +++--- 7 files changed, 23 insertions(+), 26 deletions(-) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/evaluate/FirCompileTimeConstantEvaluator.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/evaluate/FirCompileTimeConstantEvaluator.kt index 79e0b298244..ee80dfd3aba 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/evaluate/FirCompileTimeConstantEvaluator.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/evaluate/FirCompileTimeConstantEvaluator.kt @@ -28,7 +28,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirFieldSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.fir.types.impl.* import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.psi.KtElement @@ -312,8 +311,7 @@ internal object FirCompileTimeConstantEvaluator { is ConeCapturedType -> lowerType?.toConstantValueKind() ?: constructor.supertypes!!.first().toConstantValueKind() is ConeDefinitelyNotNullType -> original.toConstantValueKind() is ConeIntersectionType -> intersectedTypes.first().toConstantValueKind() - is ConeStubType -> null - is ConeIntegerLiteralType -> null + is ConeStubType, is ConeIntegerLiteralType, is ConeTypeVariableType -> null } private fun String.toConstantValueKind(): ConstantValueKind<*>? = diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/ConeTypeCompatibilityChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/ConeTypeCompatibilityChecker.kt index 1a5b99090c9..82a3b95babc 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/ConeTypeCompatibilityChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/ConeTypeCompatibilityChecker.kt @@ -241,16 +241,18 @@ object ConeTypeCompatibilityChecker { is ConeErrorType -> emptySet() // Ignore error types is ConeLookupTagBasedType -> when (this) { is ConeClassLikeType -> setOf(this) - is ConeTypeVariableType -> emptySet() is ConeTypeParameterType -> emptySet() - else -> throw IllegalStateException("missing branch for ${javaClass.name}") + else -> error("missing branch for ${javaClass.name}") } + is ConeTypeVariableType -> emptySet() is ConeDefinitelyNotNullType -> original.collectLowerBounds() is ConeIntersectionType -> intersectedTypes.flatMap { it.collectLowerBounds() }.toSet() is ConeFlexibleType -> lowerBound.collectLowerBounds() is ConeCapturedType -> constructor.supertypes?.flatMap { it.collectLowerBounds() }?.toSet().orEmpty() is ConeIntegerConstantOperatorType -> setOf(getApproximatedType()) - is ConeStubType, is ConeIntegerLiteralConstantType -> throw IllegalStateException("$this should not reach here") + is ConeStubType, is ConeIntegerLiteralConstantType -> { + error("$this should not reach here") + } } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt index 945cb0e99c6..b96d02144a4 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt @@ -832,22 +832,24 @@ fun ConeKotlinType?.collectUpperBounds(): Set { is ConeErrorType -> return // Ignore error types is ConeLookupTagBasedType -> when (type) { is ConeClassLikeType -> upperBounds.add(type) - is ConeTypeVariableType -> { - val symbol = (type.lookupTag.originalTypeParameter as? ConeTypeParameterLookupTag)?.typeParameterSymbol ?: return - symbol.resolvedBounds.forEach { collect(it.coneType) } - } is ConeTypeParameterType -> { val symbol = type.lookupTag.typeParameterSymbol symbol.resolvedBounds.forEach { collect(it.coneType) } } - else -> throw IllegalStateException("missing branch for ${javaClass.name}") + else -> error("missing branch for ${javaClass.name}") + } + is ConeTypeVariableType -> { + val symbol = (type.lookupTag.originalTypeParameter as? ConeTypeParameterLookupTag)?.typeParameterSymbol ?: return + symbol.resolvedBounds.forEach { collect(it.coneType) } } is ConeDefinitelyNotNullType -> collect(type.original) is ConeIntersectionType -> type.intersectedTypes.forEach(::collect) is ConeFlexibleType -> collect(type.upperBound) is ConeCapturedType -> type.constructor.supertypes?.forEach(::collect) is ConeIntegerConstantOperatorType -> upperBounds.add(type.getApproximatedType()) - is ConeStubType, is ConeIntegerLiteralConstantType -> throw IllegalStateException("$type should not reach here") + is ConeStubType, is ConeIntegerLiteralConstantType -> { + error("$type should not reach here") + } } } diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeVariableAndStubTypes.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeVariableAndStubTypes.kt index db915a7804e..c18c2210e5c 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeVariableAndStubTypes.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeVariableAndStubTypes.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.fir.types -import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.model.* @@ -13,10 +12,9 @@ import org.jetbrains.kotlin.types.model.* class ConeTypeVariableType( override val nullability: ConeNullability, - override val lookupTag: ConeTypeVariableTypeConstructor, + val lookupTag: ConeTypeVariableTypeConstructor, override val attributes: ConeAttributes = ConeAttributes.Empty, - // TODO: Make ConeSimpleKotlinType. KT-62420 -) : ConeLookupTagBasedType() { +) : ConeSimpleKotlinType() { override val typeArguments: Array get() = EMPTY_ARRAY override fun equals(other: Any?): Boolean { if (this === other) return true @@ -39,9 +37,8 @@ class ConeTypeVariableType( class ConeTypeVariableTypeConstructor( val debugName: String, val originalTypeParameter: TypeParameterMarker? - // TODO: Remove ConeClassifierLookupTag supertype. KT-62420 -) : ConeClassifierLookupTag(), TypeVariableTypeConstructorMarker { - override val name: Name get() = Name.identifier(debugName) +) : TypeVariableTypeConstructorMarker { + val name: Name get() = Name.identifier(debugName) var isContainedInInvariantOrContravariantPositions: Boolean = false private set diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt index 32f12522ae7..f0a3579b764 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt @@ -237,8 +237,7 @@ class Fir2IrTypeConverter( val approximated = approximateForIrOrNull()!! approximated.toIrType(typeOrigin) } - is ConeStubType -> createErrorType() - is ConeIntegerLiteralType -> createErrorType() + is ConeStubType, is ConeIntegerLiteralType, is ConeTypeVariableType -> createErrorType() } } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/LookupTagUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/LookupTagUtils.kt index 6c1c019e692..ebcc35e42c3 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/LookupTagUtils.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/LookupTagUtils.kt @@ -40,8 +40,7 @@ fun ConeClassifierLookupTag.toSymbol(useSiteSession: FirSession): FirClassifierS when (this) { is ConeClassLikeLookupTag -> toSymbol(useSiteSession) is ConeClassifierLookupTagWithFixedSymbol -> this.symbol - // TODO: replace null with error(), see KT-57921 - else -> null + else -> error("missing branch for ${javaClass.name}") } /** diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/substitution/Substitutors.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/substitution/Substitutors.kt index 79eb8c53751..de9b1c608a2 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/substitution/Substitutors.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/substitution/Substitutors.kt @@ -85,7 +85,7 @@ abstract class AbstractConeSubstitutor(protected val typeContext: ConeTypeContex private fun ConeKotlinType.substituteRecursive(): ConeKotlinType? { return when (this) { is ConeClassLikeType -> this.substituteArguments() - is ConeLookupTagBasedType -> return null + is ConeLookupTagBasedType, is ConeTypeVariableType -> return null is ConeFlexibleType -> this.substituteBounds()?.let { // TODO: may be (?) it's worth adding regular type comparison via AbstractTypeChecker // However, the simplified check here should be enough for typical flexible types @@ -156,7 +156,7 @@ abstract class AbstractConeSubstitutor(protected val typeContext: ConeTypeContex return null } - private fun ConeClassLikeType.substituteArguments(): ConeKotlinType? { + private fun ConeSimpleKotlinType.substituteArguments(): ConeKotlinType? { val newArguments by lazy { arrayOfNulls(typeArguments.size) } var initialized = false @@ -325,7 +325,7 @@ internal class ConeTypeSubstitutorByTypeConstructor( private val approximateIntegerLiterals: Boolean ) : AbstractConeSubstitutor(typeContext), TypeSubstitutorMarker { override fun substituteType(type: ConeKotlinType): ConeKotlinType? { - if (type !is ConeLookupTagBasedType && type !is ConeStubType) return null + if (type !is ConeLookupTagBasedType && type !is ConeStubType && type !is ConeTypeVariableType) return null val new = map[type.typeConstructor(typeContext)] ?: return null val approximatedIntegerLiteralType = if (approximateIntegerLiterals) new.approximateIntegerLiteralType() else new return approximatedIntegerLiteralType.updateNullabilityIfNeeded(type)?.withCombinedAttributesFrom(type)