Hey, I debugged <KT-29088> a bit (trying to learn ...
# compiler
a
Hey, I debugged KT-29088 a bit (trying to learn how the compiler works) and I think the root cause is that CompareTo only implements comparison of
Char
,
Byte
,
Short
,
Int
,
Long
,
Float
and
Double
. And for all other types, it will fallback to Int. However
CompareTo
is registered for all possible combinations of primitives, hence also for Boolean::compareTo(Boolean). I'm unsure if there is a smart trick/optimization behind using
kotlin.jvm.internal.Intrinsics::compare(Int, Int)
also for
Boolean::compareTo(Boolean)
?
It is at least working great for booleans that are not smart-casted:
Copy code
fun compareBoolean(lhs: Boolean, rhs: Boolean): Int {
    return lhs.compareTo(rhs)
}
------------------------
  public final static compareBoolean(ZZ)I
    // annotable parameter count: 2 (visible)
    // annotable parameter count: 2 (invisible)
   L0
    LINENUMBER 8 L0
    ILOAD 0
    ILOAD 1
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.compare (II)I
    IRETURN
   L1
    LOCALVARIABLE lhs Z L0 L1 0
    LOCALVARIABLE rhs Z L0 L1 1
    MAXSTACK = 2
    MAXLOCALS = 2
With the smart cast however we get:
Copy code
fun compareIfBoolean(lhs: Any, rhs: Boolean): Int? {
    if (lhs !is Boolean) return null
    return lhs.compareTo(rhs)
}
------------------------
  public final static compareIfBoolean(Ljava/lang/Object;Z)Ljava/lang/Integer;
  @Lorg/jetbrains/annotations/Nullable;() // invisible
    // annotable parameter count: 2 (visible)
    // annotable parameter count: 2 (invisible)
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
   L0
    ALOAD 0
    LDC "lhs"
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkNotNullParameter (Ljava/lang/Object;Ljava/lang/String;)V
   L1
    LINENUMBER 3 L1
    ALOAD 0
    INSTANCEOF java/lang/Boolean
    IFNE L2
    ACONST_NULL
    ARETURN
   L2
    LINENUMBER 4 L2
    ALOAD 0
    CHECKCAST java/lang/Number
    INVOKEVIRTUAL java/lang/Number.intValue ()I
    ILOAD 1
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.compare (II)I
    INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
    ARETURN
   L3
    LOCALVARIABLE lhs Ljava/lang/Object; L0 L3 0
    LOCALVARIABLE rhs Z L0 L3 1
    MAXSTACK = 2
    MAXLOCALS = 2
which causes the crash
If there is no special motivation to use
kotlin.jvm.internal.Intrinsics::compare(Int, Int)
for Booleans, this Change would fix the issue. Or do you think there would be a better approach to fix this?