[IR] Make IrTypeArgument a sealed interface

This commit is contained in:
Sergej Jaskiewicz
2023-01-19 19:35:41 +01:00
committed by Space Team
parent c65b689fa0
commit 1f76d39e66
25 changed files with 59 additions and 73 deletions
@@ -66,7 +66,6 @@ class TransitiveExportCollector(val context: JsIrBackendContext) {
is IrType -> substitute(typeSubstitutionMap) is IrType -> substitute(typeSubstitutionMap)
is IrTypeProjection -> type.substitute(typeSubstitutionMap) is IrTypeProjection -> type.substitute(typeSubstitutionMap)
is IrStarProjection -> context.irBuiltIns.anyNType is IrStarProjection -> context.irBuiltIns.anyNType
else -> error("Unexpected ir type argument")
} }
} }
@@ -39,7 +39,6 @@ fun IrType.asString(): String = when (this) {
private fun IrTypeArgument.asString(): String = when (this) { private fun IrTypeArgument.asString(): String = when (this) {
is IrStarProjection -> "*" is IrStarProjection -> "*"
is IrTypeProjection -> variance.label + (if (variance != Variance.INVARIANT) " " else "") + type.asString() is IrTypeProjection -> variance.label + (if (variance != Variance.INVARIANT) " " else "") + type.asString()
else -> error("Unexpected kind of IrTypeArgument: " + javaClass.simpleName)
} }
private fun IrClassifierSymbol.asString() = when (this) { private fun IrClassifierSymbol.asString() = when (this) {
@@ -442,7 +442,7 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
private val parameterTypes = (irFunctionReference.type as IrSimpleType).arguments.map { private val parameterTypes = (irFunctionReference.type as IrSimpleType).arguments.map {
when (it) { when (it) {
is IrTypeProjection -> it.type is IrTypeProjection -> it.type
else -> context.irBuiltIns.anyNType is IrStarProjection -> context.irBuiltIns.anyNType
} }
} }
private val argumentTypes = parameterTypes.dropLast(1) private val argumentTypes = parameterTypes.dropLast(1)
@@ -111,7 +111,7 @@ private class MainMethodGenerationLowering(private val context: JvmBackendContex
is IrTypeProjection -> { is IrTypeProjection -> {
(argType.variance != Variance.IN_VARIANCE) && argType.type.isStringClassType() (argType.variance != Variance.IN_VARIANCE) && argType.type.isStringClassType()
} }
else -> false is IrStarProjection -> false
} }
} }
@@ -150,7 +150,6 @@ private fun IrType.isArrayOrNullableArrayOf(context: JvmBackendContext, element:
this is IrSimpleType && (isArray() || isNullableArray()) && arguments.size == 1 && element == when (val it = arguments[0]) { this is IrSimpleType && (isArray() || isNullableArray()) && arguments.size == 1 && element == when (val it = arguments[0]) {
is IrStarProjection -> context.irBuiltIns.anyClass is IrStarProjection -> context.irBuiltIns.anyClass
is IrTypeProjection -> if (it.variance == Variance.IN_VARIANCE) context.irBuiltIns.anyClass else it.type.classifierOrNull is IrTypeProjection -> if (it.variance == Variance.IN_VARIANCE) context.irBuiltIns.anyClass else it.type.classifierOrNull
else -> null
} }
// Match `fun <T> toArray(prototype: Array<T>): Array<T>` // Match `fun <T> toArray(prototype: Array<T>): Array<T>`
@@ -62,7 +62,6 @@ fun IrType.eraseTypeParameters(): IrType = when (this) {
private fun IrTypeArgument.eraseTypeParameters(): IrTypeArgument = when (this) { private fun IrTypeArgument.eraseTypeParameters(): IrTypeArgument = when (this) {
is IrStarProjection -> this is IrStarProjection -> this
is IrTypeProjection -> makeTypeProjection(type.eraseTypeParameters(), variance) is IrTypeProjection -> makeTypeProjection(type.eraseTypeParameters(), variance)
else -> error("Unknown IrTypeArgument kind: $this")
} }
/** /**
@@ -147,7 +146,6 @@ fun IrType.eraseToScope(visibleTypeParameters: Set<IrTypeParameter>): IrType {
private fun IrTypeArgument.eraseToScope(visibleTypeParameters: Set<IrTypeParameter>): IrTypeArgument = when (this) { private fun IrTypeArgument.eraseToScope(visibleTypeParameters: Set<IrTypeParameter>): IrTypeArgument = when (this) {
is IrStarProjection -> this is IrStarProjection -> this
is IrTypeProjection -> makeTypeProjection(type.eraseToScope(visibleTypeParameters), variance) is IrTypeProjection -> makeTypeProjection(type.eraseToScope(visibleTypeParameters), variance)
else -> error("unknown type projection kind: ${render()}")
} }
fun collectVisibleTypeParameters(scopeOwner: IrTypeParametersContainer): Set<IrTypeParameter> = fun collectVisibleTypeParameters(scopeOwner: IrTypeParametersContainer): Set<IrTypeParameter> =
@@ -53,7 +53,6 @@ internal class KTypeState(val irType: IrType, override val irClass: IrClass) : R
is IrSimpleType -> Variance.INVARIANT is IrSimpleType -> Variance.INVARIANT
is IrTypeProjection -> this.variance is IrTypeProjection -> this.variance
is IrStarProjection -> null is IrStarProjection -> null
else -> TODO()
} }
} }
@@ -1174,7 +1174,6 @@ private fun makeKotlinType(
when (it) { when (it) {
is IrTypeProjection -> TypeProjectionImpl(it.variance, it.type.toIrBasedKotlinType()) is IrTypeProjection -> TypeProjectionImpl(it.variance, it.type.toIrBasedKotlinType())
is IrStarProjection -> StarProjectionImpl(classDescriptor.typeConstructor.parameters[index]) is IrStarProjection -> StarProjectionImpl(classDescriptor.typeConstructor.parameters[index])
else -> error(it)
} }
} }
@@ -92,7 +92,10 @@ abstract class IrSimpleType(kotlinType: KotlinType?) : IrTypeBase(kotlinType), S
get() = nullability == SimpleTypeNullability.MARKED_NULLABLE get() = nullability == SimpleTypeNullability.MARKED_NULLABLE
} }
interface IrTypeArgument : TypeArgumentMarker { /**
* An argument for a generic parameter. Can be either [IrTypeProjection], or [IrStarProjection].
*/
sealed interface IrTypeArgument : TypeArgumentMarker {
override fun equals(other: Any?): Boolean override fun equals(other: Any?): Boolean
override fun hashCode(): Int override fun hashCode(): Int
} }
@@ -31,7 +31,6 @@ abstract class AbstractIrTypeSubstitutor(private val irBuiltIns: IrBuiltIns) : T
when (val typeArgument = getSubstitutionArgument(it)) { when (val typeArgument = getSubstitutionArgument(it)) {
is IrStarProjection -> irBuiltIns.anyNType // TODO upper bound for T is IrStarProjection -> irBuiltIns.anyNType // TODO upper bound for T
is IrTypeProjection -> typeArgument.type.run { if (type.isMarkedNullable()) makeNullable() else this } is IrTypeProjection -> typeArgument.type.run { if (type.isMarkedNullable()) makeNullable() else this }
else -> error("unknown type argument")
} }
} ?: substituteType(type) } ?: substituteType(type)
} }
@@ -52,21 +51,22 @@ abstract class AbstractIrTypeSubstitutor(private val irBuiltIns: IrBuiltIns) : T
} }
private fun substituteTypeArgument(typeArgument: IrTypeArgument): IrTypeArgument { private fun substituteTypeArgument(typeArgument: IrTypeArgument): IrTypeArgument {
if (typeArgument is IrStarProjection) return typeArgument when (typeArgument) {
is IrStarProjection -> return typeArgument
require(typeArgument is IrTypeProjection) is IrTypeProjection -> {
val type = typeArgument.type
val type = typeArgument.type if (type is IrSimpleType) {
if (type is IrSimpleType) { val classifier = type.classifier
val classifier = type.classifier if (classifier is IrTypeParameterSymbol) {
if (classifier is IrTypeParameterSymbol) { val newArgument = getSubstitutionArgument(classifier)
val newArgument = getSubstitutionArgument(classifier) return if (newArgument is IrTypeProjection) {
return if (newArgument is IrTypeProjection) { makeTypeProjection(newArgument.type, typeArgument.variance)
makeTypeProjection(newArgument.type, typeArgument.variance) } else newArgument
} else newArgument }
}
return makeTypeProjection(substituteType(typeArgument.type), typeArgument.variance)
} }
} }
return makeTypeProjection(substituteType(typeArgument.type), typeArgument.variance)
} }
} }
@@ -61,8 +61,8 @@ fun IrType.getArrayElementType(irBuiltIns: IrBuiltIns): IrType =
argument.type argument.type
is IrStarProjection -> is IrStarProjection ->
irBuiltIns.anyNType irBuiltIns.anyNType
else -> null ->
error("Unexpected array argument type: $argument") error("Unexpected array argument type: null")
} }
} else { } else {
val classifier = this.classOrNull!! val classifier = this.classOrNull!!
@@ -150,7 +150,6 @@ private fun makeKotlinType(
when (it) { when (it) {
is IrTypeProjection -> TypeProjectionImpl(it.variance, it.type.toKotlinType()) is IrTypeProjection -> TypeProjectionImpl(it.variance, it.type.toKotlinType())
is IrStarProjection -> StarProjectionImpl((classifier.descriptor as ClassDescriptor).typeConstructor.parameters[index]) is IrStarProjection -> StarProjectionImpl((classifier.descriptor as ClassDescriptor).typeConstructor.parameters[index])
else -> error(it)
} }
} }
return classifier.descriptor.defaultType.replace(newArguments = kotlinTypeArguments).makeNullableAsSpecified(hasQuestionMark) return classifier.descriptor.defaultType.replace(newArguments = kotlinTypeArguments).makeNullableAsSpecified(hasQuestionMark)
@@ -41,10 +41,10 @@ class DeepCopyTypeRemapper(
} }
private fun remapTypeArgument(typeArgument: IrTypeArgument): IrTypeArgument = private fun remapTypeArgument(typeArgument: IrTypeArgument): IrTypeArgument =
if (typeArgument is IrTypeProjection) when (typeArgument) {
makeTypeProjection(this.remapType(typeArgument.type), typeArgument.variance) is IrTypeProjection -> makeTypeProjection(this.remapType(typeArgument.type), typeArgument.variance)
else is IrStarProjection -> typeArgument
typeArgument }
private fun IrTypeAbbreviation.remapTypeAbbreviation() = private fun IrTypeAbbreviation.remapTypeAbbreviation() =
IrTypeAbbreviationImpl( IrTypeAbbreviationImpl(
@@ -43,10 +43,10 @@ class IrTypeParameterRemapper(
?: this ?: this
private fun IrTypeArgument.remap() = private fun IrTypeArgument.remap() =
if (this is IrTypeProjection) when (this) {
makeTypeProjection(remapType(type), variance) is IrTypeProjection -> makeTypeProjection(remapType(type), variance)
else is IrStarProjection -> this
this }
private fun IrTypeAbbreviation.remap() = private fun IrTypeAbbreviation.remap() =
IrTypeAbbreviationImpl( IrTypeAbbreviationImpl(
@@ -100,10 +100,9 @@ fun IrType.substitute(substitutionMap: Map<IrTypeParameterSymbol, IrType>): IrTy
} }
val newArguments = arguments.map { val newArguments = arguments.map {
if (it is IrTypeProjection) { when (it) {
makeTypeProjection(it.type.substitute(substitutionMap), it.variance) is IrTypeProjection -> makeTypeProjection(it.type.substitute(substitutionMap), it.variance)
} else { is IrStarProjection -> it
it
} }
} }
@@ -987,7 +987,7 @@ fun IrType.remapTypeParameters(
it.type.remapTypeParameters(source, target, srcToDstParameterMap), it.type.remapTypeParameters(source, target, srcToDstParameterMap),
it.variance it.variance
) )
else -> it is IrStarProjection -> it
} }
}, },
annotations annotations
@@ -593,7 +593,6 @@ fun IrTypeArgument.render() =
when (this) { when (this) {
is IrStarProjection -> "*" is IrStarProjection -> "*"
is IrTypeProjection -> "$variance ${type.render()}" is IrTypeProjection -> "$variance ${type.render()}"
else -> throw AssertionError("Unexpected IrTypeArgument: $this")
} }
internal inline fun <T, Buffer : Appendable> Buffer.appendIterableWith( internal inline fun <T, Buffer : Appendable> Buffer.appendIterableWith(
@@ -785,8 +784,6 @@ private fun IrTypeArgument.renderTypeArgument(renderer: RenderIrElementVisitor?,
if (variance != Variance.INVARIANT) append(' ') if (variance != Variance.INVARIANT) append(' ')
append(type.renderTypeWithRenderer(renderer, verboseErrorTypes)) append(type.renderTypeWithRenderer(renderer, verboseErrorTypes))
} }
else -> "IrTypeArgument[$this]"
} }
private fun renderTypeAnnotations(annotations: List<IrConstructorCall>, renderer: RenderIrElementVisitor?, verboseErrorTypes: Boolean) = private fun renderTypeAnnotations(annotations: List<IrConstructorCall>, renderer: RenderIrElementVisitor?, verboseErrorTypes: Boolean) =
@@ -42,10 +42,10 @@ class SimpleTypeRemapper(
} }
private fun remapTypeArgument(typeArgument: IrTypeArgument): IrTypeArgument = private fun remapTypeArgument(typeArgument: IrTypeArgument): IrTypeArgument =
if (typeArgument is IrTypeProjection) when (typeArgument) {
makeTypeProjection(this.remapType(typeArgument.type), typeArgument.variance) is IrTypeProjection -> makeTypeProjection(this.remapType(typeArgument.type), typeArgument.variance)
else is IrStarProjection -> typeArgument
typeArgument }
private fun IrTypeAbbreviation.remapTypeAbbreviation() = private fun IrTypeAbbreviation.remapTypeAbbreviation() =
IrTypeAbbreviationImpl( IrTypeAbbreviationImpl(
@@ -374,7 +374,6 @@ open class IrFileSerializer(
return when (argument) { return when (argument) {
is IrStarProjection -> serializeIrStarProjection() is IrStarProjection -> serializeIrStarProjection()
is IrTypeProjection -> serializeIrTypeProjection(argument) is IrTypeProjection -> serializeIrTypeProjection(argument)
else -> TODO("Unexpected type argument kind: $argument")
} }
} }
@@ -484,7 +483,6 @@ open class IrFileSerializer(
kind = when (this) { kind = when (this) {
is IrStarProjection -> IrTypeArgumentKind.STAR is IrStarProjection -> IrTypeArgumentKind.STAR
is IrTypeProjection -> IrTypeArgumentKind.PROJECTION is IrTypeProjection -> IrTypeArgumentKind.PROJECTION
else -> error("Unexpected type argument kind: $this")
}, },
variance = (this as? IrTypeProjection)?.variance, variance = (this as? IrTypeProjection)?.variance,
type = (this as? IrTypeProjection)?.type?.toIrTypeKey type = (this as? IrTypeProjection)?.type?.toIrTypeKey
@@ -101,7 +101,7 @@ internal class AddFunctionSupertypeToSuspendFunctionLowering(val context: Contex
require(type.classOrNull == continuationClassSymbol) require(type.classOrNull == continuationClassSymbol)
when (val typeArgument = (type as IrSimpleType).arguments.single()) { when (val typeArgument = (type as IrSimpleType).arguments.single()) {
is IrTypeProjection -> typeArgument.type is IrTypeProjection -> typeArgument.type
else -> context.irBuiltIns.anyNType is IrStarProjection -> context.irBuiltIns.anyNType
} }
} else { } else {
type type
@@ -154,7 +154,6 @@ internal class KTypeGenerator(
when (argument) { when (argument) {
is IrStarProjection -> irConstantInt(-1) is IrStarProjection -> irConstantInt(-1)
is IrTypeProjection -> irConstantInt(mapVariance(argument.variance)) is IrTypeProjection -> irConstantInt(mapVariance(argument.variance))
else -> error("Unexpected IrTypeArgument: $argument (${argument::class})")
} }
}) })
val type = irConstantArray( val type = irConstantArray(
@@ -163,7 +162,6 @@ internal class KTypeGenerator(
when (argument) { when (argument) {
is IrStarProjection -> irConstantPrimitive(irNull()) is IrStarProjection -> irConstantPrimitive(irNull())
is IrTypeProjection -> irKType(argument.type, leaveReifiedForLater, seenTypeParameters) is IrTypeProjection -> irKType(argument.type, leaveReifiedForLater, seenTypeParameters)
else -> error("Unexpected IrTypeArgument: $argument (${argument::class})")
} }
}) })
return irConstantObject( return irConstantObject(
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall
import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrStarProjection
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.IrTypeProjection import org.jetbrains.kotlin.ir.types.IrTypeProjection
import org.jetbrains.kotlin.ir.types.impl.buildSimpleType import org.jetbrains.kotlin.ir.types.impl.buildSimpleType
@@ -37,20 +38,21 @@ internal class SamSuperTypesChecker(private val context: Context,
this.nullability = this@eraseProjections.nullability this.nullability = this@eraseProjections.nullability
this.annotations = this@eraseProjections.annotations this.annotations = this@eraseProjections.annotations
this.arguments = this@eraseProjections.arguments.mapIndexed { index, argument -> this.arguments = this@eraseProjections.arguments.mapIndexed { index, argument ->
if (argument !is IrTypeProjection) when (argument) {
argument is IrStarProjection -> argument
else { is IrTypeProjection -> {
if (mode == Mode.THROW && argument.variance != Variance.INVARIANT) { if (mode == Mode.THROW && argument.variance != Variance.INVARIANT) {
context.reportCompilationError( context.reportCompilationError(
"Unexpected variance in super type argument: ${argument.variance} @$index", irFile, owner) "Unexpected variance in super type argument: ${argument.variance} @$index", irFile, owner)
}
val newArgumentType = if (recurse) {
argument.type.eraseProjections(owner)
} else {
// See the explanation at the SamSuperTypesChecker constructor call sites.
argument.type
}
makeTypeProjection(newArgumentType, Variance.INVARIANT)
} }
val newArgumentType = if (recurse) {
argument.type.eraseProjections(owner)
} else {
// See the explanation at the SamSuperTypesChecker constructor call sites.
argument.type
}
makeTypeProjection(newArgumentType, Variance.INVARIANT)
} }
} }
} }
@@ -183,7 +183,6 @@ fun IrType.substitute(map: Map<IrTypeParameterSymbol, IrType>): IrType {
when (it) { when (it) {
is IrTypeProjection -> makeTypeProjection(it.type.substitute(map), it.variance) is IrTypeProjection -> makeTypeProjection(it.type.substitute(map), it.variance)
is IrStarProjection -> it is IrStarProjection -> it
else -> error(it)
} }
} }
IrSimpleTypeImpl(classifier, nullability, newArguments, annotations) IrSimpleTypeImpl(classifier, nullability, newArguments, annotations)
@@ -150,7 +150,6 @@ fun IrTypeArgument.upperBound(builtIns: IrBuiltIns): IrType =
else else
builtIns.anyNType builtIns.anyNType
} }
else -> error("Unknown type argument: ${render()}")
} }
private fun IrClass.getSimpleFunction(name: String): IrSimpleFunctionSymbol? = private fun IrClass.getSimpleFunction(name: String): IrSimpleFunctionSymbol? =
@@ -194,7 +194,6 @@ fun IrTypeArgument.upperBound(builtIns: IrBuiltIns): IrType =
else else
builtIns.anyNType builtIns.anyNType
} }
else -> error("Unknown type argument: ${render()}")
} }
private fun IrClass.getSimpleFunction(name: String): IrSimpleFunctionSymbol? = private fun IrClass.getSimpleFunction(name: String): IrSimpleFunctionSymbol? =