Fix UnsafeNumber being applied incorrectly in hierarchical commonization
^KT-64376
This commit is contained in:
committed by
Space Team
parent
3c03e388d2
commit
0aa7b6f6ad
+15
-8
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.commonizer.utils.*
|
||||
|
||||
private typealias BitWidth = Int
|
||||
|
||||
private class SubstitutableNumbers(private val numbers: Map<CirEntityId, BitWidth>) {
|
||||
private class SubstitutableNumbers(val numbers: Map<CirEntityId, BitWidth>) {
|
||||
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<CirClassType> {
|
||||
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()
|
||||
}
|
||||
|
||||
|
||||
+11
-8
@@ -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<OptimisticNumbersTypeCommonizer.OptimisticCommonizationMarker>()?.let { isMarkedTypeFound = true }
|
||||
?: super.visit(classType)
|
||||
if (classType.getAttachment<OptimisticNumbersTypeCommonizer.OptimisticCommonizationMarker>() != null) {
|
||||
isOptimisticallyCommonizedType = true
|
||||
}
|
||||
if (OptimisticNumbersTypeCommonizer.isOptimisticallyCommonizableNumber(classType.classifierId)) {
|
||||
isOptimisticallyCommonizableNumberType = true
|
||||
}
|
||||
super.visit(classType)
|
||||
}
|
||||
})
|
||||
|
||||
return isMarkedTypeFound
|
||||
return isOptimisticallyCommonizedType || (isDerivedFromOptimisticallyCommonizedType && isOptimisticallyCommonizableNumberType)
|
||||
}
|
||||
|
||||
private typealias RenderedType = String
|
||||
|
||||
-1
@@ -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()
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user