Rework support of Iterator.iterator optimization in ForLoopsLowering

- Fix the predicate used for finding the member function `next`: check
  that there's no extension receiver parameter, don't filter out
  abstract functions.
- Do not copy iterator expression, instead change the type in all
  references to the iterator variable.
- Fix some style issues.

 #KT-47171 Fixed
This commit is contained in:
Alexander Udalov
2022-02-25 23:24:35 +01:00
committed by Alexander Udalov
parent 1b776bd5b6
commit 157db778fd
15 changed files with 293 additions and 172 deletions
@@ -0,0 +1,24 @@
// TARGET_BACKEND: JVM
// WITH_STDLIB
fun iterate(iterator: MyIterator): String {
for (x in iterator) return x
return "Fail"
}
abstract class MyIterator : Iterator<String> {
override fun hasNext(): Boolean = true
abstract override fun next(): String
}
class MyIteratorImpl : MyIterator() {
override fun next(): String = "OK"
}
fun box(): String = iterate(MyIteratorImpl())
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 0 java/util/Iterator.next
// 1 MyIterator.next
// 1 MyIteratorImpl.next
@@ -0,0 +1,24 @@
// TARGET_BACKEND: JVM
// WITH_STDLIB
fun myFun(iterator: MyLongIterator) {
for (x in iterator) {
assert(x == 42L)
}
}
class MyLongIterator : Iterator<Long> {
private var count = 1
override fun hasNext(): Boolean = count-- > 0
override fun next(): Long = 42L
}
fun box(): String {
myFun(MyLongIterator())
return "OK"
}
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 0 java/util/Iterator.next
// 2 MyLongIterator.next
@@ -0,0 +1,27 @@
// TARGET_BACKEND: JVM
// WITH_STDLIB
fun myFun(iterator: MyUIntIterator) {
for (x in iterator) {
assert(x == 42u)
}
}
class MyUIntIterator : Iterator<UInt> {
private var count = 1
override fun hasNext(): Boolean = count-- > 0
override fun next(): UInt = 42u
}
fun box(): String {
myFun(MyUIntIterator())
return "OK"
}
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 0 java/util/Iterator.hasNext \(\)Z
// 0 java/util/Iterator.next \(\)Ljava/lang/Object;
// 1 MyUIntIterator.hasNext \(\)Z
// 1 public synthetic bridge next\(\)Ljava/lang/Object;
// 2 MyUIntIterator.next-pVg5ArA \(\)I
@@ -0,0 +1,22 @@
// TARGET_BACKEND: JVM
// WITH_STDLIB
fun iterate(iterator: MyIterator): String {
for (x in iterator) return x
return "Fail"
}
class MyIterator : Iterator<String> {
@JvmName("unrelated")
private fun String.next(): String = throw AssertionError("Should not be called")
override fun hasNext(): Boolean = true
override fun next(): String = "OK"
}
fun box(): String = iterate(MyIterator())
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 0 java/util/Iterator.next
// 2 MyIterator.next