[IR] Create primitive iterators in IrBuiltIns

This change is required to fix stdlib compilation with enabled
linking via signature. All primitive iterators are considered to be
builtins and are created during compile time as deserialized
declarations (at least in K1). But if we meet the definition of some
primitive iterator in code, for example, during stdlib compilation,
we will end up with two different descriptors (deserialized and lazy)
that describe the same entity. Because of that we have conflicts in
symbol table:
* For descriptors, we will end up with multiple IR declarations
that describe the same class, but with different descriptors. With
some magic compilation still works.
* For signatures, we will end up with only one IR declaration in the
table, but it will have wrong deserialized (instead of lazy)
descriptor.

In the end, this change allows us to initialize iterators in advance
with correct descriptor.

#KT-56230
This commit is contained in:
Ivan Kylchik
2023-08-02 18:53:30 +02:00
committed by Space Team
parent 782d5e86f6
commit 5f2de9dbff
19 changed files with 289 additions and 16 deletions
@@ -0,0 +1,31 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND_K2: JVM_IR
// IGNORE_BACKEND_K2_MULTI_MODULE: JVM_IR JVM_IR_SERIALIZE
// ALLOW_KOTLIN_PACKAGE
// Note: order of files is important
// MODULE: kotlin_stdlib
// FILE: _Arrays.kt
package kotlin.collections
public inline fun ByteArray.customFirst(predicate: (Byte) -> Boolean): Byte {
for (element in this) if (predicate(element)) return element
throw NoSuchElementException("Array contains no element matching the predicate.")
}
// FILE: PrimitiveIterators.kt
package kotlin.collections
public abstract class ByteIterator : Iterator<Byte> {
override final fun next() = nextByte()
/** Returns the next value in the sequence without boxing. */
public abstract fun nextByte(): Byte
}
// Module: main(kotlin_stdlib)
// FILE: main.kt
fun box(): String {
byteArrayOf(1, 2, 3).customFirst { it == 1.toByte() }
return "OK"
}