Leave boxing for compareTo/areEqual methods for inline classes
Inline classes can override methods and thus introduce side effects
This commit is contained in:
@@ -15,7 +15,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||
import org.jetbrains.kotlin.builtins.UnsignedTypes;
|
||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.HashCode;
|
||||
@@ -148,6 +147,10 @@ public class AsmUtil {
|
||||
return primitiveTypeByBoxedType.get(boxedType);
|
||||
}
|
||||
|
||||
public static boolean isBoxedPrimitiveType(@NotNull Type boxedType) {
|
||||
return primitiveTypeByBoxedType.get(boxedType) != null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Type unboxUnlessPrimitive(@NotNull Type boxedOrPrimitiveType) {
|
||||
if (isPrimitive(boxedOrPrimitiveType)) return boxedOrPrimitiveType;
|
||||
|
||||
+5
@@ -67,6 +67,7 @@ class BoxedValueDescriptor(
|
||||
|
||||
var isSafeToRemove = true; private set
|
||||
val unboxedType: Type = getUnboxedType(boxedType, generationState)
|
||||
val isInlineClassValue = isInlineClassValue(boxedType)
|
||||
|
||||
fun getAssociatedInsns() = associatedInsns.toList()
|
||||
|
||||
@@ -120,3 +121,7 @@ fun unboxedTypeOfInlineClass(boxedType: Type, state: GenerationState): Type? {
|
||||
val descriptor = state.jvmBackendClassResolver.resolveToClassDescriptors(boxedType).singleOrNull() ?: return null
|
||||
return state.typeMapper.mapType(descriptor.defaultType)
|
||||
}
|
||||
|
||||
private fun isInlineClassValue(boxedType: Type): Boolean {
|
||||
return !AsmUtil.isBoxedPrimitiveType(boxedType) && boxedType != AsmTypes.K_CLASS_TYPE
|
||||
}
|
||||
|
||||
+5
-4
@@ -276,14 +276,15 @@ fun isProgressionClass(type: Type) =
|
||||
isRangeOrProgression(buildFqNameByInternal(type.internalName))
|
||||
|
||||
fun AbstractInsnNode.isAreEqualIntrinsicForSameTypedBoxedValues(values: List<BasicValue>) =
|
||||
isAreEqualIntrinsic() && areSameTypedBoxedValues(values)
|
||||
isAreEqualIntrinsic() && areSameTypedPrimitiveBoxedValues(values)
|
||||
|
||||
fun areSameTypedBoxedValues(values: List<BasicValue>): Boolean {
|
||||
fun areSameTypedPrimitiveBoxedValues(values: List<BasicValue>): Boolean {
|
||||
if (values.size != 2) return false
|
||||
val (v1, v2) = values
|
||||
return v1 is BoxedBasicValue &&
|
||||
v2 is BoxedBasicValue &&
|
||||
v1.descriptor.unboxedType == v2.descriptor.unboxedType
|
||||
v1.descriptor.unboxedType == v2.descriptor.unboxedType &&
|
||||
!v1.descriptor.isInlineClassValue && !v2.descriptor.isInlineClassValue
|
||||
}
|
||||
|
||||
fun AbstractInsnNode.isAreEqualIntrinsic() =
|
||||
@@ -299,7 +300,7 @@ fun canValuesBeUnboxedForAreEqual(values: List<BasicValue>, generationState: Gen
|
||||
values.none { getUnboxedType(it.type, generationState) in shouldUseEqualsForWrappers }
|
||||
|
||||
fun AbstractInsnNode.isJavaLangComparableCompareToForSameTypedBoxedValues(values: List<BasicValue>) =
|
||||
isJavaLangComparableCompareTo() && areSameTypedBoxedValues(values)
|
||||
isJavaLangComparableCompareTo() && areSameTypedPrimitiveBoxedValues(values)
|
||||
|
||||
fun AbstractInsnNode.isJavaLangComparableCompareTo() =
|
||||
isMethodInsnWith(Opcodes.INVOKEINTERFACE) {
|
||||
|
||||
Reference in New Issue
Block a user