diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/OptimisticNumbersTypeCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/OptimisticNumbersTypeCommonizer.kt index 6e7bec9361d..b31db7d3c24 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/OptimisticNumbersTypeCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/OptimisticNumbersTypeCommonizer.kt @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.commonizer.utils.* private typealias BitWidth = Int -private class SubstitutableNumbers(private val numbers: Map) { +private class SubstitutableNumbers(val numbers: Map) { operator fun contains(id: CirEntityId) = id in numbers fun choose(first: CirClassType, second: CirClassType): CirClassType? { val firstBitWidth = numbers[first.classifierId] ?: return null @@ -71,14 +71,21 @@ private val floatingPointVars = SubstitutableNumbers( ) internal object OptimisticNumbersTypeCommonizer : AssociativeCommonizer { - override fun commonize(first: CirClassType, second: CirClassType): CirClassType? { - val result = signedIntegers.choose(first, second) - ?: unsignedIntegers.choose(first, second) - ?: floatingPoints.choose(first, second) - ?: signedVarIntegers.choose(first, second) - ?: unsignedVarIntegers.choose(first, second) - ?: floatingPointVars.choose(first, second) + private val commonizableNumberTypes = listOf( + signedIntegers, + unsignedIntegers, + floatingPoints, + signedVarIntegers, + unsignedVarIntegers, + floatingPointVars, + ) + private val commonizableNumberIdentifiers = commonizableNumberTypes.flatMap { it.numbers.keys }.toSet() + + fun isOptimisticallyCommonizableNumber(identifier: CirEntityId): Boolean = identifier in commonizableNumberIdentifiers + + override fun commonize(first: CirClassType, second: CirClassType): CirClassType? { + val result = commonizableNumberTypes.firstNotNullOfOrNull { it.choose(first, second) } return result?.withMarker() } diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/UnsafeNumberAnnotationUtils.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/UnsafeNumberAnnotationUtils.kt index 9346b1e2654..e87973239d5 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/UnsafeNumberAnnotationUtils.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/UnsafeNumberAnnotationUtils.kt @@ -52,23 +52,26 @@ private fun shouldCreateAnnotation( if (!settings.getSetting(OptimisticNumberCommonizationEnabledKey)) return false - val annotatedInputDeclarationPresent = inputDeclarations.any { declaration -> + val isDerivedFromOptimisticallyCommonizedType = inputDeclarations.any { declaration -> declaration.annotations.any { annotation -> annotation is UnsafeNumberAnnotation } } - if (annotatedInputDeclarationPresent) - return true - - var isMarkedTypeFound = false + var isOptimisticallyCommonizedType = false + var isOptimisticallyCommonizableNumberType = false commonizedType.accept(object : BasicCirTypeVisitor() { override fun visit(classType: CirClassType) { - classType.getAttachment()?.let { isMarkedTypeFound = true } - ?: super.visit(classType) + if (classType.getAttachment() != null) { + isOptimisticallyCommonizedType = true + } + if (OptimisticNumbersTypeCommonizer.isOptimisticallyCommonizableNumber(classType.classifierId)) { + isOptimisticallyCommonizableNumberType = true + } + super.visit(classType) } }) - return isMarkedTypeFound + return isOptimisticallyCommonizedType || (isDerivedFromOptimisticallyCommonizedType && isOptimisticallyCommonizableNumberType) } private typealias RenderedType = String diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalOptimisticNumbersTypeCommonizerTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalOptimisticNumbersTypeCommonizerTest.kt index f10cb923c6f..5c217e505c0 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalOptimisticNumbersTypeCommonizerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalOptimisticNumbersTypeCommonizerTest.kt @@ -972,7 +972,6 @@ class HierarchicalOptimisticNumbersTypeCommonizerTest : AbstractInlineSourcesCom result.assertCommonized( "(a, b, c)", """ expect class X - @UnsafeNumber(["a: kotlin.Short", "b: kotlin.Int", "c: kotlin.Any"]) expect fun foo(x: X): X """.trimIndent() )