diff --git a/compiler/fir/analysis-tests/testData/resolve/inference/nestedExtensionFunctionType.txt b/compiler/fir/analysis-tests/testData/resolve/inference/nestedExtensionFunctionType.txt index d300044a22d..9306a470f7f 100644 --- a/compiler/fir/analysis-tests/testData/resolve/inference/nestedExtensionFunctionType.txt +++ b/compiler/fir/analysis-tests/testData/resolve/inference/nestedExtensionFunctionType.txt @@ -4,16 +4,16 @@ FILE: nestedExtensionFunctionType.kt public final fun test_0(a: R|A|, f: R|A.() -> kotlin/Unit|): R|kotlin/Unit| { R|/f|.R|FakeOverride|(R|/a|) } - public final fun test_1(a: R|A|, ys: R|kotlin/collections/List>|): R|kotlin/Unit| { - lval : R|kotlin/collections/Iterator>| = R|/ys|.R|FakeOverride>|>|() + public final fun test_1(a: R|A|, ys: R|kotlin/collections/List<@ExtensionFunctionType kotlin/Function1>|): R|kotlin/Unit| { + lval : R|kotlin/collections/Iterator<@ExtensionFunctionType kotlin/Function1>| = R|/ys|.R|FakeOverride>|>|() while(R|/|.R|kotlin/collections/Iterator.hasNext|()) { lval y: R|(A) -> kotlin/Unit| = R|/|.R|FakeOverride kotlin/Unit|>|() R|/y|.R|FakeOverride|(R|/a|) } } - public final fun test_2(a: R|A|, vararg zs: @R|kotlin/ExtensionFunctionType|() R|kotlin/Array>|): R|kotlin/Unit| { - lval : R|kotlin/collections/Iterator>| = R|/zs|.R|FakeOverride)>|>|() + public final fun test_2(a: R|A|, vararg zs: @R|kotlin/ExtensionFunctionType|() R|kotlin/Array>|): R|kotlin/Unit| { + lval : R|kotlin/collections/Iterator<@ExtensionFunctionType kotlin/Function1>| = R|/zs|.R|FakeOverride)>|>|() while(R|/|.R|kotlin/collections/Iterator.hasNext|()) { lval z: R|(A) -> kotlin/Unit| = R|/|.R|FakeOverride kotlin/Unit|>|() R|/z|.R|FakeOverride|(R|/a|) diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/CompilerConeAttributes.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/CompilerConeAttributes.kt index ac42940b8e6..50f70ccc588 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/CompilerConeAttributes.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/CompilerConeAttributes.kt @@ -19,6 +19,8 @@ object CompilerConeAttributes { override fun isSubtypeOf(other: Exact?): Boolean = true override val key: KClass = Exact::class + + override fun toString(): String = "@Exact" } object NoInfer : ConeAttribute() { @@ -29,6 +31,8 @@ object CompilerConeAttributes { override fun isSubtypeOf(other: NoInfer?): Boolean = true override val key: KClass = NoInfer::class + + override fun toString(): String = "@NoInfer" } object ExtensionFunctionType : ConeAttribute() { @@ -39,6 +43,8 @@ object CompilerConeAttributes { override fun isSubtypeOf(other: ExtensionFunctionType?): Boolean = true override val key: KClass = ExtensionFunctionType::class + + override fun toString(): String = "@ExtensionFunctionType" } object UnsafeVariance : ConeAttribute() { @@ -49,6 +55,8 @@ object CompilerConeAttributes { override fun isSubtypeOf(other: UnsafeVariance?): Boolean = true override val key: KClass = UnsafeVariance::class + + override fun toString(): String = "@UnsafeVariance" } } diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeAttributes.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeAttributes.kt index 94bb1b45ae6..a7b35cc3a42 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeAttributes.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeAttributes.kt @@ -18,11 +18,15 @@ abstract class ConeAttribute> { abstract fun intersect(other: @UnsafeVariance T?): T? abstract fun isSubtypeOf(other: @UnsafeVariance T?): Boolean + abstract override fun toString(): String + abstract val key: KClass } @OptIn(Protected::class) -class ConeAttributes private constructor(attributes: List>) : AttributeArrayOwner, ConeAttribute<*>>() { +class ConeAttributes private constructor(attributes: List>) : AttributeArrayOwner, ConeAttribute<*>>(), + Iterable> { + companion object : TypeRegistry, ConeAttribute<*>>() { inline fun > attributeAccessor(): ReadOnlyProperty { @Suppress("UNCHECKED_CAST") @@ -54,6 +58,10 @@ class ConeAttributes private constructor(attributes: List>) : A return perform(other) { this.intersect(it) } } + override fun iterator(): Iterator> { + return arrayMap.iterator() + } + private inline fun perform(other: ConeAttributes, op: ConeAttribute<*>.(ConeAttribute<*>?) -> ConeAttribute<*>?): ConeAttributes { if (this.isEmpty() && other.isEmpty()) return this val attributes = mutableListOf>() diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/TypeRenderer.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/TypeRenderer.kt index 77f7cc44a6b..8967d795c53 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/TypeRenderer.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/TypeRenderer.kt @@ -12,12 +12,13 @@ import kotlin.contracts.contract fun ConeKotlinType.render(): String { val nullabilitySuffix = if (this !is ConeKotlinErrorType && this !is ConeClassErrorType) nullability.suffix else "" return when (this) { - is ConeTypeVariableType -> "TypeVariable(${this.lookupTag.name})" + is ConeTypeVariableType -> "${renderAttributes()}TypeVariable(${this.lookupTag.name})" is ConeDefinitelyNotNullType -> "${original.render()}!!" - is ConeClassErrorType -> "ERROR CLASS: ${diagnostic.reason}" - is ConeCapturedType -> "CapturedType(${constructor.projection.render()})" + is ConeClassErrorType -> "${renderAttributes()}ERROR CLASS: ${diagnostic.reason}" + is ConeCapturedType -> "${renderAttributes()}CapturedType(${constructor.projection.render()})" is ConeClassLikeType -> { buildString { + append(renderAttributes()) append(lookupTag.classId.asString()) if (typeArguments.isNotEmpty()) { append(typeArguments.joinToString(prefix = "<", postfix = ">") { @@ -27,7 +28,7 @@ fun ConeKotlinType.render(): String { } } is ConeLookupTagBasedType -> { - lookupTag.name.asString() + "${renderAttributes()}${lookupTag.name.asString()}" } is ConeFlexibleType -> { buildString { @@ -41,15 +42,20 @@ fun ConeKotlinType.render(): String { is ConeIntersectionType -> { intersectedTypes.joinToString( separator = " & ", - prefix = "it(", + prefix = "${renderAttributes()}it(", postfix = ")" ) } - is ConeStubType -> "Stub: $variable" - is ConeIntegerLiteralType -> "ILT: $value" + is ConeStubType -> "${renderAttributes()}Stub: $variable" + is ConeIntegerLiteralType -> "${renderAttributes()}ILT: $value" } + nullabilitySuffix } +private fun ConeKotlinType.renderAttributes(): String { + if (!attributes.any()) return "" + return attributes.joinToString(" ", postfix = " ") { it.toString() } +} + private fun ConeTypeProjection.render(): String { return when (this) { ConeStarProjection -> "*"