IR: remove dependency of IrTypeSubstitutor on IrBuiltIns

It was only used in one place incorrectly anyway.
This commit is contained in:
Alexander Udalov
2023-09-11 17:54:39 +02:00
committed by Space Team
parent c2dfe415f3
commit 41f736a665
6 changed files with 41 additions and 56 deletions
@@ -247,7 +247,7 @@ internal abstract class IrExpectActualMatchingContext(
val expectParameters = expectTypeParameters.castAll<IrTypeParameterSymbol>() val expectParameters = expectTypeParameters.castAll<IrTypeParameterSymbol>()
val actualParameters = actualTypeParameters.castAll<IrTypeParameterSymbol>() val actualParameters = actualTypeParameters.castAll<IrTypeParameterSymbol>()
val actualTypes = actualParameters.map { it.owner.defaultType } val actualTypes = actualParameters.map { it.owner.defaultType }
val substitutor = IrTypeSubstitutor(expectParameters, actualTypes, typeContext.irBuiltIns, allowEmptySubstitution = true) val substitutor = IrTypeSubstitutor(expectParameters, actualTypes, allowEmptySubstitution = true)
return when (parentSubstitutor) { return when (parentSubstitutor) {
null -> substitutor null -> substitutor
is AbstractIrTypeSubstitutor -> IrChainedSubstitutor(parentSubstitutor, substitutor) is AbstractIrTypeSubstitutor -> IrChainedSubstitutor(parentSubstitutor, substitutor)
@@ -50,15 +50,10 @@ class WrapInlineDeclarationsWithReifiedTypeParametersLowering(val context: Backe
if (!owner.isInlineFunWithReifiedParameter()) { if (!owner.isInlineFunWithReifiedParameter()) {
return expression return expression
} }
val substitutionMap = expression.typeSubstitutionMap val substitutionMap = expression.typeSubstitutionMap.entries
.entries
.map { (key, value) ->
key to (value as IrTypeArgument)
}
val typeSubstitutor = IrTypeSubstitutor( val typeSubstitutor = IrTypeSubstitutor(
substitutionMap.map { it.first }, substitutionMap.map { it.key },
substitutionMap.map { it.second }, substitutionMap.map { it.value as IrTypeArgument },
context.irBuiltIns
) )
val function = irFactory.buildFun { val function = irFactory.buildFun {
@@ -233,10 +233,6 @@ internal class SamDelegatingLambdaBuilder(private val jvmContext: JvmBackendCont
throw AssertionError("Simple type expected: ${irType.render()}") throw AssertionError("Simple type expected: ${irType.render()}")
val irClassSymbol = irType.classOrNull val irClassSymbol = irType.classOrNull
?: throw AssertionError("Class type expected: ${irType.render()}") ?: throw AssertionError("Class type expected: ${irType.render()}")
return IrTypeSubstitutor( return IrTypeSubstitutor(irClassSymbol.owner.typeParameters.map { it.symbol }, irType.arguments)
irClassSymbol.owner.typeParameters.map { it.symbol },
irType.arguments,
jvmContext.irBuiltIns
)
} }
} }
@@ -5,10 +5,10 @@
package org.jetbrains.kotlin.ir.types package org.jetbrains.kotlin.ir.types
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.impl.* import org.jetbrains.kotlin.ir.types.impl.*
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
import org.jetbrains.kotlin.utils.memoryOptimizedMap import org.jetbrains.kotlin.utils.memoryOptimizedMap
@@ -17,60 +17,58 @@ abstract class AbstractIrTypeSubstitutor : TypeSubstitutorMarker {
abstract fun substitute(type: IrType): IrType abstract fun substitute(type: IrType): IrType
} }
abstract class BaseIrTypeSubstitutor(private val irBuiltIns: IrBuiltIns) : AbstractIrTypeSubstitutor() { abstract class BaseIrTypeSubstitutor : AbstractIrTypeSubstitutor() {
private fun IrType.typeParameterConstructor(): IrTypeParameterSymbol? {
return if (this is IrSimpleType) classifier as? IrTypeParameterSymbol
else null
}
abstract fun getSubstitutionArgument(typeParameter: IrTypeParameterSymbol): IrTypeArgument abstract fun getSubstitutionArgument(typeParameter: IrTypeParameterSymbol): IrTypeArgument
abstract fun isEmptySubstitution(): Boolean abstract fun isEmptySubstitution(): Boolean
final override fun substitute(type: IrType): IrType { final override fun substitute(type: IrType): IrType {
if (isEmptySubstitution()) return type if (isEmptySubstitution()) return type
return substituteType(type) return when (val result = substituteType(type)) {
is IrStarProjection -> error("Cannot replace top-level type with star projection: ${type.render()}")
is IrTypeProjection -> result.type
}
} }
private fun substituteType(irType: IrType): IrType { private fun substituteType(irType: IrType): IrTypeArgument {
val substitutedTypeParameter = irType.typeParameterConstructor()?.let { val classifier = (irType as? IrSimpleType)?.classifier
when (val typeArgument = getSubstitutionArgument(it)) { if (classifier is IrTypeParameterSymbol) {
is IrStarProjection -> irBuiltIns.anyNType // TODO upper bound for T return when (val typeArgument = getSubstitutionArgument(classifier)) {
is IrTypeProjection -> typeArgument.type.mergeNullability(irType) is IrStarProjection -> typeArgument
.addAnnotations(irType.annotations) is IrTypeProjection -> makeTypeProjection(
typeArgument.type.mergeNullability(irType).addAnnotations(irType.annotations),
typeArgument.variance,
)
} }
} }
if (substitutedTypeParameter != null) {
return substitutedTypeParameter
}
return when (irType) { return when (irType) {
is IrSimpleType -> with(irType.toBuilder()) { is IrSimpleType -> with(irType.toBuilder()) {
arguments = irType.arguments.memoryOptimizedMap { substituteTypeArgument(it) } arguments = irType.arguments.memoryOptimizedMap { substituteTypeArgument(it) }
buildSimpleType() buildSimpleType()
} }
is IrDynamicType, is IrDynamicType, is IrErrorType -> makeTypeProjection(irType, Variance.INVARIANT)
is IrErrorType -> irType
else -> error("Unexpected type: $irType") else -> error("Unexpected type: $irType")
} }
} }
private fun substituteTypeArgument(typeArgument: IrTypeArgument): IrTypeArgument { private fun substituteTypeArgument(typeArgument: IrTypeArgument): IrTypeArgument =
return when (typeArgument) { when (typeArgument) {
is IrStarProjection -> typeArgument is IrStarProjection -> typeArgument
is IrTypeProjection -> makeTypeProjection(substituteType(typeArgument.type), typeArgument.variance) is IrTypeProjection -> when (val replacement = substituteType(typeArgument.type)) {
is IrStarProjection -> replacement
is IrTypeProjection -> makeTypeProjection(
replacement.type, TypeSubstitutor.combine(typeArgument.variance, replacement.variance)
)
}
} }
}
} }
class IrTypeSubstitutor( class IrTypeSubstitutor(
typeParameters: List<IrTypeParameterSymbol>, typeParameters: List<IrTypeParameterSymbol>,
typeArguments: List<IrTypeArgument>, typeArguments: List<IrTypeArgument>,
irBuiltIns: IrBuiltIns, private val allowEmptySubstitution: Boolean = false,
private val allowEmptySubstitution: Boolean = false ) : BaseIrTypeSubstitutor() {
) : BaseIrTypeSubstitutor(irBuiltIns) {
init { init {
assert(typeParameters.size == typeArguments.size) { assert(typeParameters.size == typeArguments.size) {
"Unexpected number of type arguments: ${typeArguments.size}\n" + "Unexpected number of type arguments: ${typeArguments.size}\n" +
@@ -95,9 +93,7 @@ class IrCapturedTypeSubstitutor(
typeParameters: List<IrTypeParameterSymbol>, typeParameters: List<IrTypeParameterSymbol>,
typeArguments: List<IrTypeArgument>, typeArguments: List<IrTypeArgument>,
capturedTypes: List<IrCapturedType?>, capturedTypes: List<IrCapturedType?>,
irBuiltIns: IrBuiltIns ) : BaseIrTypeSubstitutor() {
) : BaseIrTypeSubstitutor(irBuiltIns) {
init { init {
assert(typeArguments.size == typeParameters.size) assert(typeArguments.size == typeParameters.size)
assert(capturedTypes.size == typeParameters.size) assert(capturedTypes.size == typeParameters.size)
@@ -276,7 +276,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
val newArguments = ArrayList<IrTypeArgument>(typeArguments.size) val newArguments = ArrayList<IrTypeArgument>(typeArguments.size)
val typeSubstitutor = IrCapturedTypeSubstitutor(typeParameters.memoryOptimizedMap { it.symbol }, typeArguments, capturedTypes, irBuiltIns) val typeSubstitutor = IrCapturedTypeSubstitutor(typeParameters.memoryOptimizedMap { it.symbol }, typeArguments, capturedTypes)
for (index in typeArguments.indices) { for (index in typeArguments.indices) {
val oldArgument = typeArguments[index] val oldArgument = typeArguments[index]
@@ -498,7 +498,6 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
IrTypeSubstitutor( IrTypeSubstitutor(
(this as IrType).getClass()!!.typeParameters.memoryOptimizedMap { it.symbol }, (this as IrType).getClass()!!.typeParameters.memoryOptimizedMap { it.symbol },
(this as? IrSimpleType)?.arguments.orEmpty(), (this as? IrSimpleType)?.arguments.orEmpty(),
irBuiltIns
).substitute(type as IrType) ).substitute(type as IrType)
} }
@@ -581,7 +580,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
override fun substitutionSupertypePolicy(type: SimpleTypeMarker): TypeCheckerState.SupertypesPolicy { override fun substitutionSupertypePolicy(type: SimpleTypeMarker): TypeCheckerState.SupertypesPolicy {
require(type is IrSimpleType) require(type is IrSimpleType)
val parameters = extractTypeParameters((type.classifier as IrClassSymbol).owner).memoryOptimizedMap { it.symbol } val parameters = extractTypeParameters((type.classifier as IrClassSymbol).owner).memoryOptimizedMap { it.symbol }
val typeSubstitutor = IrTypeSubstitutor(parameters, type.arguments, irBuiltIns) val typeSubstitutor = IrTypeSubstitutor(parameters, type.arguments)
return object : TypeCheckerState.SupertypesPolicy.DoCustomTransform() { return object : TypeCheckerState.SupertypesPolicy.DoCustomTransform() {
override fun transformType(state: TypeCheckerState, type: KotlinTypeMarker): SimpleTypeMarker { override fun transformType(state: TypeCheckerState, type: KotlinTypeMarker): SimpleTypeMarker {
@@ -602,11 +601,11 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
typeParameters += key as IrTypeParameterSymbol typeParameters += key as IrTypeParameterSymbol
typeArguments += value as IrTypeArgument typeArguments += value as IrTypeArgument
} }
return IrTypeSubstitutor(typeParameters, typeArguments, irBuiltIns) return IrTypeSubstitutor(typeParameters, typeArguments)
} }
override fun createEmptySubstitutor(): TypeSubstitutorMarker { override fun createEmptySubstitutor(): TypeSubstitutorMarker {
return IrTypeSubstitutor(emptyList(), emptyList(), irBuiltIns) return IrTypeSubstitutor(emptyList(), emptyList())
} }
override fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker { override fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker {
@@ -23,8 +23,8 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.* import org.jetbrains.kotlin.ir.types.impl.*
import org.jetbrains.kotlin.utils.memoryOptimizedMap
import org.jetbrains.kotlin.ir.util.parentAsClass import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.utils.memoryOptimizedMap
import org.jetbrains.kotlin.backend.common.serialization.proto.IrBlock as ProtoBlock import org.jetbrains.kotlin.backend.common.serialization.proto.IrBlock as ProtoBlock
import org.jetbrains.kotlin.backend.common.serialization.proto.IrBlockBody as ProtoBlockBody import org.jetbrains.kotlin.backend.common.serialization.proto.IrBlockBody as ProtoBlockBody
import org.jetbrains.kotlin.backend.common.serialization.proto.IrBranch as ProtoBranch import org.jetbrains.kotlin.backend.common.serialization.proto.IrBranch as ProtoBranch
@@ -193,8 +193,7 @@ class IrBodyDeserializer(
// TODO: probably a bit more abstraction possible here up to `IrMemberAccessExpression` // TODO: probably a bit more abstraction possible here up to `IrMemberAccessExpression`
// but at this point further complexization looks overengineered // but at this point further complexization looks overengineered
private class IrAnnotationType(private val builtIns: IrBuiltIns) : IrDelegatedSimpleType() { private class IrAnnotationType : IrDelegatedSimpleType() {
var irConstructorCall: IrConstructorCall? = null var irConstructorCall: IrConstructorCall? = null
override val delegate: IrSimpleType by lazy { resolveType() } override val delegate: IrSimpleType by lazy { resolveType() }
@@ -228,13 +227,13 @@ class IrBodyDeserializer(
typeParameterSymbols.add(typeParameter.symbol) typeParameterSymbols.add(typeParameter.symbol)
} }
val substitutor = IrTypeSubstitutor(typeParameterSymbols, typeArguments, builtIns) val substitutor = IrTypeSubstitutor(typeParameterSymbols, typeArguments)
return substitutor.substitute(rawType) as IrSimpleType return substitutor.substitute(rawType) as IrSimpleType
} }
} }
fun deserializeAnnotation(proto: ProtoConstructorCall): IrConstructorCall { fun deserializeAnnotation(proto: ProtoConstructorCall): IrConstructorCall {
val irType = IrAnnotationType(builtIns) val irType = IrAnnotationType()
// TODO: use real coordinates // TODO: use real coordinates
return deserializeConstructorCall(proto, 0, 0, irType).also { irType.irConstructorCall = it } return deserializeConstructorCall(proto, 0, 0, irType).also { irType.irConstructorCall = it }
} }