[FIR] Flatten ConeAttributeWithConeType when transforming

This is necessary to prevent exponential growth of the attribute
structure.
Since we usually care for the most inner value of a
ConeAttributeWithConeType like EnhancedTypeForWarningAttribute, this
shouldn't alter any behavior.
This commit is contained in:
Kirill Rakhman
2024-01-16 14:03:06 +01:00
committed by Space Team
parent b8ff04004a
commit cf494ada0b
@@ -63,7 +63,11 @@ inline fun <T : ConeAttributeWithConeType<T>> ConeAttributeWithConeType<T>.trans
): ConeAttributeWithConeType<T>? {
val transformedType = transform(coneType) ?: return null
if (transformedType == coneType) return this
return copyWith(transformedType)
// If the type contains the attribute itself, use the nested type from the attribute to prevent exponential growth.
// As an example, consider a substitution {T -> Attr(Foo) Bar} applied to a type `Attr(T) T`.
// If we don't flatten the attribute chain, we would get `Attr(Attr(Foo) Bar) Bar`.
return copyWith(transformedType.attributes[key]?.coneType ?: transformedType)
}
typealias ConeAttributeKey = KClass<out ConeAttribute<*>>
@@ -120,8 +124,13 @@ class ConeAttributes private constructor(attributes: List<ConeAttribute<*>>) : A
}
operator fun contains(attributeKey: KClass<out ConeAttribute<*>>): Boolean {
return get(attributeKey) != null
}
operator fun <T : ConeAttribute<*>> get(attributeKey: KClass<T>) : T? {
val index = getId(attributeKey)
return arrayMap[index] != null
@Suppress("UNCHECKED_CAST")
return arrayMap[index] as T?
}
operator fun plus(attribute: ConeAttribute<*>): ConeAttributes {