JVM IR: do not use old KotlinTypeMapper when coercing inline classes

KotlinTypeMapper.mapInlineClassTypeAsDeclaration and
mapUnderlyingTypeOfInlineClassType invoked mapType which is defined in
descriptorBasedTypeSignatureMapping.kt and works on KotlinType.

It didn't lead to any problems, other than the fact that we were
constructing IrBasedClassDescriptor in JVM IR, and then KotlinType to
pass it to mapType, on each call to StackValue.boxInlineClass or
unboxInlineClass, which seems wasteful.

Instead of this, refactor these utilities to use type markers instead,
pass IrType and IrTypeMapper directly from JVM IR, and move the "static
type mapper" logic (which is used only in the old backend) out of
KotlinTypeMapper.
This commit is contained in:
Alexander Udalov
2021-03-31 17:03:38 +02:00
parent b5ecccb610
commit b59ac5d8f6
16 changed files with 162 additions and 98 deletions
@@ -11,10 +11,19 @@ import org.jetbrains.kotlin.fir.resolve.substitution.createTypeSubstitutorByType
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeLookupTagBasedType
import org.jetbrains.kotlin.fir.types.ConeTypeContext
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.types.model.typeConstructor
fun ConeKotlinType.substitutedUnderlyingTypeForInlineClass(session: FirSession, context: ConeTypeContext): ConeKotlinType? {
internal fun ConeKotlinType.substitutedUnderlyingTypeForInlineClass(session: FirSession, context: ConeTypeContext): ConeKotlinType? {
val unsubstitutedType = unsubstitutedUnderlyingTypeForInlineClass(session) ?: return null
val substitutor = createTypeSubstitutorByTypeConstructor(mapOf(this.typeConstructor(context) to this), context)
return substitutor.substituteOrNull(unsubstitutedType)
}
internal fun ConeKotlinType.unsubstitutedUnderlyingTypeForInlineClass(session: FirSession): ConeKotlinType? {
val symbol = (this.fullyExpandedType(session) as? ConeLookupTagBasedType)
?.lookupTag
?.toSymbol(session) as? FirRegularClassSymbol
@@ -24,8 +33,5 @@ fun ConeKotlinType.substitutedUnderlyingTypeForInlineClass(session: FirSession,
if (!firClass.status.isInline) return null
val constructor = firClass.declarations.singleOrNull { it is FirConstructor && it.isPrimary } as FirConstructor? ?: return null
val valueParameter = constructor.valueParameters.singleOrNull() ?: return null
val unsubstitutedType = valueParameter.returnTypeRef.coneType
val substitutor = createTypeSubstitutorByTypeConstructor(mapOf(this.typeConstructor(context) to this), context)
return substitutor.substituteOrNull(unsubstitutedType)
return valueParameter.returnTypeRef.coneType
}
@@ -497,6 +497,11 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
?: session.builtinTypes.nullableAnyType.type
}
override fun KotlinTypeMarker.getUnsubstitutedUnderlyingType(): KotlinTypeMarker? {
require(this is ConeKotlinType)
return unsubstitutedUnderlyingTypeForInlineClass(session)
}
override fun KotlinTypeMarker.getSubstitutedUnderlyingType(): KotlinTypeMarker? {
require(this is ConeKotlinType)
return substitutedUnderlyingTypeForInlineClass(session, this@ConeTypeContext)