K2: make type variable based types not class like
#KT-57921 Fixed #KT-62420 Fixed
This commit is contained in:
committed by
Space Team
parent
6053c94c8a
commit
1ceec4d6d7
+1
-3
@@ -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.impl.FirPropertySymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.impl.*
|
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
@@ -312,8 +311,7 @@ internal object FirCompileTimeConstantEvaluator {
|
|||||||
is ConeCapturedType -> lowerType?.toConstantValueKind() ?: constructor.supertypes!!.first().toConstantValueKind()
|
is ConeCapturedType -> lowerType?.toConstantValueKind() ?: constructor.supertypes!!.first().toConstantValueKind()
|
||||||
is ConeDefinitelyNotNullType -> original.toConstantValueKind()
|
is ConeDefinitelyNotNullType -> original.toConstantValueKind()
|
||||||
is ConeIntersectionType -> intersectedTypes.first().toConstantValueKind()
|
is ConeIntersectionType -> intersectedTypes.first().toConstantValueKind()
|
||||||
is ConeStubType -> null
|
is ConeStubType, is ConeIntegerLiteralType, is ConeTypeVariableType -> null
|
||||||
is ConeIntegerLiteralType -> null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun String.toConstantValueKind(): ConstantValueKind<*>? =
|
private fun String.toConstantValueKind(): ConstantValueKind<*>? =
|
||||||
|
|||||||
+5
-3
@@ -241,16 +241,18 @@ object ConeTypeCompatibilityChecker {
|
|||||||
is ConeErrorType -> emptySet() // Ignore error types
|
is ConeErrorType -> emptySet() // Ignore error types
|
||||||
is ConeLookupTagBasedType -> when (this) {
|
is ConeLookupTagBasedType -> when (this) {
|
||||||
is ConeClassLikeType -> setOf(this)
|
is ConeClassLikeType -> setOf(this)
|
||||||
is ConeTypeVariableType -> emptySet()
|
|
||||||
is ConeTypeParameterType -> 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 ConeDefinitelyNotNullType -> original.collectLowerBounds()
|
||||||
is ConeIntersectionType -> intersectedTypes.flatMap { it.collectLowerBounds() }.toSet()
|
is ConeIntersectionType -> intersectedTypes.flatMap { it.collectLowerBounds() }.toSet()
|
||||||
is ConeFlexibleType -> lowerBound.collectLowerBounds()
|
is ConeFlexibleType -> lowerBound.collectLowerBounds()
|
||||||
is ConeCapturedType -> constructor.supertypes?.flatMap { it.collectLowerBounds() }?.toSet().orEmpty()
|
is ConeCapturedType -> constructor.supertypes?.flatMap { it.collectLowerBounds() }?.toSet().orEmpty()
|
||||||
is ConeIntegerConstantOperatorType -> setOf(getApproximatedType())
|
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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -832,22 +832,24 @@ fun ConeKotlinType?.collectUpperBounds(): Set<ConeClassLikeType> {
|
|||||||
is ConeErrorType -> return // Ignore error types
|
is ConeErrorType -> return // Ignore error types
|
||||||
is ConeLookupTagBasedType -> when (type) {
|
is ConeLookupTagBasedType -> when (type) {
|
||||||
is ConeClassLikeType -> upperBounds.add(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 -> {
|
is ConeTypeParameterType -> {
|
||||||
val symbol = type.lookupTag.typeParameterSymbol
|
val symbol = type.lookupTag.typeParameterSymbol
|
||||||
symbol.resolvedBounds.forEach { collect(it.coneType) }
|
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 ConeDefinitelyNotNullType -> collect(type.original)
|
||||||
is ConeIntersectionType -> type.intersectedTypes.forEach(::collect)
|
is ConeIntersectionType -> type.intersectedTypes.forEach(::collect)
|
||||||
is ConeFlexibleType -> collect(type.upperBound)
|
is ConeFlexibleType -> collect(type.upperBound)
|
||||||
is ConeCapturedType -> type.constructor.supertypes?.forEach(::collect)
|
is ConeCapturedType -> type.constructor.supertypes?.forEach(::collect)
|
||||||
is ConeIntegerConstantOperatorType -> upperBounds.add(type.getApproximatedType())
|
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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-7
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.types
|
package org.jetbrains.kotlin.fir.types
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.types.model.*
|
import org.jetbrains.kotlin.types.model.*
|
||||||
|
|
||||||
@@ -13,10 +12,9 @@ import org.jetbrains.kotlin.types.model.*
|
|||||||
|
|
||||||
class ConeTypeVariableType(
|
class ConeTypeVariableType(
|
||||||
override val nullability: ConeNullability,
|
override val nullability: ConeNullability,
|
||||||
override val lookupTag: ConeTypeVariableTypeConstructor,
|
val lookupTag: ConeTypeVariableTypeConstructor,
|
||||||
override val attributes: ConeAttributes = ConeAttributes.Empty,
|
override val attributes: ConeAttributes = ConeAttributes.Empty,
|
||||||
// TODO: Make ConeSimpleKotlinType. KT-62420
|
) : ConeSimpleKotlinType() {
|
||||||
) : ConeLookupTagBasedType() {
|
|
||||||
override val typeArguments: Array<out ConeTypeProjection> get() = EMPTY_ARRAY
|
override val typeArguments: Array<out ConeTypeProjection> get() = EMPTY_ARRAY
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
@@ -39,9 +37,8 @@ class ConeTypeVariableType(
|
|||||||
class ConeTypeVariableTypeConstructor(
|
class ConeTypeVariableTypeConstructor(
|
||||||
val debugName: String,
|
val debugName: String,
|
||||||
val originalTypeParameter: TypeParameterMarker?
|
val originalTypeParameter: TypeParameterMarker?
|
||||||
// TODO: Remove ConeClassifierLookupTag supertype. KT-62420
|
) : TypeVariableTypeConstructorMarker {
|
||||||
) : ConeClassifierLookupTag(), TypeVariableTypeConstructorMarker {
|
val name: Name get() = Name.identifier(debugName)
|
||||||
override val name: Name get() = Name.identifier(debugName)
|
|
||||||
|
|
||||||
var isContainedInInvariantOrContravariantPositions: Boolean = false
|
var isContainedInInvariantOrContravariantPositions: Boolean = false
|
||||||
private set
|
private set
|
||||||
|
|||||||
@@ -237,8 +237,7 @@ class Fir2IrTypeConverter(
|
|||||||
val approximated = approximateForIrOrNull()!!
|
val approximated = approximateForIrOrNull()!!
|
||||||
approximated.toIrType(typeOrigin)
|
approximated.toIrType(typeOrigin)
|
||||||
}
|
}
|
||||||
is ConeStubType -> createErrorType()
|
is ConeStubType, is ConeIntegerLiteralType, is ConeTypeVariableType -> createErrorType()
|
||||||
is ConeIntegerLiteralType -> createErrorType()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,8 +40,7 @@ fun ConeClassifierLookupTag.toSymbol(useSiteSession: FirSession): FirClassifierS
|
|||||||
when (this) {
|
when (this) {
|
||||||
is ConeClassLikeLookupTag -> toSymbol(useSiteSession)
|
is ConeClassLikeLookupTag -> toSymbol(useSiteSession)
|
||||||
is ConeClassifierLookupTagWithFixedSymbol -> this.symbol
|
is ConeClassifierLookupTagWithFixedSymbol -> this.symbol
|
||||||
// TODO: replace null with error(), see KT-57921
|
else -> error("missing branch for ${javaClass.name}")
|
||||||
else -> null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+3
-3
@@ -85,7 +85,7 @@ abstract class AbstractConeSubstitutor(protected val typeContext: ConeTypeContex
|
|||||||
private fun ConeKotlinType.substituteRecursive(): ConeKotlinType? {
|
private fun ConeKotlinType.substituteRecursive(): ConeKotlinType? {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is ConeClassLikeType -> this.substituteArguments()
|
is ConeClassLikeType -> this.substituteArguments()
|
||||||
is ConeLookupTagBasedType -> return null
|
is ConeLookupTagBasedType, is ConeTypeVariableType -> return null
|
||||||
is ConeFlexibleType -> this.substituteBounds()?.let {
|
is ConeFlexibleType -> this.substituteBounds()?.let {
|
||||||
// TODO: may be (?) it's worth adding regular type comparison via AbstractTypeChecker
|
// TODO: may be (?) it's worth adding regular type comparison via AbstractTypeChecker
|
||||||
// However, the simplified check here should be enough for typical flexible types
|
// 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
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeClassLikeType.substituteArguments(): ConeKotlinType? {
|
private fun ConeSimpleKotlinType.substituteArguments(): ConeKotlinType? {
|
||||||
val newArguments by lazy { arrayOfNulls<ConeTypeProjection>(typeArguments.size) }
|
val newArguments by lazy { arrayOfNulls<ConeTypeProjection>(typeArguments.size) }
|
||||||
var initialized = false
|
var initialized = false
|
||||||
|
|
||||||
@@ -325,7 +325,7 @@ internal class ConeTypeSubstitutorByTypeConstructor(
|
|||||||
private val approximateIntegerLiterals: Boolean
|
private val approximateIntegerLiterals: Boolean
|
||||||
) : AbstractConeSubstitutor(typeContext), TypeSubstitutorMarker {
|
) : AbstractConeSubstitutor(typeContext), TypeSubstitutorMarker {
|
||||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
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 new = map[type.typeConstructor(typeContext)] ?: return null
|
||||||
val approximatedIntegerLiteralType = if (approximateIntegerLiterals) new.approximateIntegerLiteralType() else new
|
val approximatedIntegerLiteralType = if (approximateIntegerLiterals) new.approximateIntegerLiteralType() else new
|
||||||
return approximatedIntegerLiteralType.updateNullabilityIfNeeded(type)?.withCombinedAttributesFrom(type)
|
return approximatedIntegerLiteralType.updateNullabilityIfNeeded(type)?.withCombinedAttributesFrom(type)
|
||||||
|
|||||||
Reference in New Issue
Block a user