diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrType.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrType.kt index 7d3b469e71c..de8b67fe631 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrType.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrType.kt @@ -30,6 +30,10 @@ interface IrErrorType : IrType interface IrDynamicType : IrType, DynamicTypeMarker +interface IrDefinitelyNotNullType : IrType, DefinitelyNotNullTypeMarker { + val original: IrType +} + interface IrSimpleType : IrType, SimpleTypeMarker, TypeArgumentListMarker { val classifier: IrClassifierSymbol val hasQuestionMark: Boolean diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeUtils.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeUtils.kt index 95a17ed2f46..1c12671a0ed 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeUtils.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeUtils.kt @@ -34,6 +34,7 @@ fun IrType.isSubtypeOf(superType: IrType, typeSystem: IrTypeSystemContext): Bool fun IrType.isNullable(): Boolean = when (this) { + is IrDefinitelyNotNullType -> false is IrSimpleType -> when (val classifier = classifier) { is IrClassSymbol -> hasQuestionMark is IrTypeParameterSymbol -> hasQuestionMark || classifier.owner.superTypes.any(IrType::isNullable) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrSimpleTypeImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrSimpleTypeImpl.kt index d5b10de090e..9449183d533 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrSimpleTypeImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrSimpleTypeImpl.kt @@ -35,7 +35,7 @@ abstract class IrAbstractSimpleType(kotlinType: KotlinType?) : IrTypeBase(kotlin arguments.hashCode() } -abstract class IrDelegatedSimpleType : IrAbstractSimpleType(null) { +abstract class IrDelegatedSimpleType(kotlinType: KotlinType? = null) : IrAbstractSimpleType(kotlinType) { protected abstract val delegate: IrSimpleType @@ -51,6 +51,14 @@ abstract class IrDelegatedSimpleType : IrAbstractSimpleType(null) { get() = delegate.annotations } +// TODO: This implementation is aligned with FE representation of DefinitelyNotNull (DNN) type but +// in fact DNN is special case of more general `IntersectionType` +// so someday it should be reconsidered +class IrDefinitelyNotNullTypeImpl(kotlinType: KotlinType?, original: IrType) : IrDelegatedSimpleType(kotlinType), IrDefinitelyNotNullType { + override val delegate: IrSimpleType = original as IrSimpleType + override val original: IrType + get() = delegate +} class IrSimpleTypeImpl( kotlinType: KotlinType?, @@ -123,6 +131,7 @@ class IrTypeProjectionImpl internal constructor( fun makeTypeProjection(type: IrType, variance: Variance): IrTypeProjection = when { type is IrCapturedType -> IrTypeProjectionImpl(type, variance) + type is IrDefinitelyNotNullType -> IrTypeProjectionImpl(type, variance) type is IrTypeProjection && type.variance == variance -> type type is IrSimpleType -> type.toBuilder().apply { this.variance = variance }.buildTypeProjection() type is IrDynamicType -> IrDynamicTypeImpl(null, type.annotations, variance) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyTypeRemapper.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyTypeRemapper.kt index 8eebfc11f56..1feb9993acd 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyTypeRemapper.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyTypeRemapper.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.ir.util import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.types.* +import org.jetbrains.kotlin.ir.types.impl.IrDefinitelyNotNullTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrTypeAbbreviationImpl import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection @@ -26,11 +27,10 @@ class DeepCopyTypeRemapper( // TODO } - override fun remapType(type: IrType): IrType = - if (type !is IrSimpleType) - type - else - IrSimpleTypeImpl( + override fun remapType(type: IrType): IrType { + return when (type) { + is IrDefinitelyNotNullType -> IrDefinitelyNotNullTypeImpl(null, remapType(type.original)) + is IrSimpleType -> IrSimpleTypeImpl( null, symbolRemapper.getReferencedClassifier(type.classifier), type.hasQuestionMark, @@ -38,6 +38,9 @@ class DeepCopyTypeRemapper( type.annotations.map { it.transform(deepCopy, null) as IrConstructorCall }, type.abbreviation?.remapTypeAbbreviation() ) + else -> type + } + } private fun remapTypeArgument(typeArgument: IrTypeArgument): IrTypeArgument = if (typeArgument is IrTypeProjection) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt index f18e521c4ee..b07c3d132fc 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt @@ -113,6 +113,8 @@ class RenderIrElementVisitor(private val normalizeNames: Boolean = false, privat is IrErrorType -> "IrErrorType(${if (verboseErrorTypes) originalKotlinType else null})" + is IrDefinitelyNotNullType -> "{${original.render()} & Any}" + is IrSimpleType -> buildTrimEnd { append(classifier.renderClassifierFqn()) if (arguments.isNotEmpty()) { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/dumpKotlinLike.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/dumpKotlinLike.kt index c9f1d377472..ab72becb099 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/dumpKotlinLike.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/dumpKotlinLike.kt @@ -6,7 +6,10 @@ package org.jetbrains.kotlin.ir.util import com.intellij.openapi.util.text.StringUtil -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.descriptors.DescriptorVisibilities +import org.jetbrains.kotlin.descriptors.DescriptorVisibility +import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.declarations.* @@ -415,6 +418,11 @@ private class KotlinLikeDumper(val p: Printer, val options: KotlinLikeDumpOption // TODO don't print `Any?` as upper bound? printAnnotationsWithNoIndent() when (this) { + is IrDefinitelyNotNullType -> { + p.printWithNoIndent("(") + original.printTypeWithNoIndent() + p.printWithNoIndent(" & Any)") + } is IrSimpleType -> { // TODO abbreviation