FIR CFG: process called-in-place lambdas as loops

This commit is contained in:
pyos
2022-06-16 12:58:55 +02:00
committed by Dmitriy Novozhilov
parent 8214e4f806
commit 06c7572ee5
16 changed files with 116 additions and 31 deletions
@@ -28,7 +28,7 @@ fun test() {
var s: String? = null
s = ""
atLeastOnce {
<!SMARTCAST_IMPOSSIBLE!>s<!>.length // unstable since lambda can be called twice
s<!UNSAFE_CALL!>.<!>length // unstable since lambda can be called twice
s = null
var s2: String? = null
s2 = ""
@@ -30,7 +30,7 @@ fun baz(s: String?) {
<!SMARTCAST_IMPOSSIBLE!>x<!>.hashCode()
}
run {
<!SMARTCAST_IMPOSSIBLE!>x<!>.hashCode()
x<!UNSAFE_CALL!>.<!>hashCode()
x = null
}
}
@@ -40,7 +40,7 @@ fun gaz(s: String?) {
var x = s
if (x != null) {
run {
<!SMARTCAST_IMPOSSIBLE!>x<!>.hashCode()
x<!UNSAFE_CALL!>.<!>hashCode()
x = null
}
run {
@@ -0,0 +1,11 @@
// FIR_IDENTICAL
fun main() {
var p: String?
var block: () -> Int = { 1 }
p = "2"
run {
block = { <!SMARTCAST_IMPOSSIBLE!>p<!>.length }
}
p = null
block()
}
@@ -0,0 +1,3 @@
package
public fun main(): kotlin.Unit
@@ -8,7 +8,8 @@ public fun foo() {
} else if (s == null) {
return -2
} else {
return <!SMARTCAST_IMPOSSIBLE!>s<!>.length // Here smartcast is possible, at least in principle
// Smart cast might be unsafe if function is invoked twice concurrently
return <!SMARTCAST_IMPOSSIBLE!>s<!>.length
}
}
if (s != null) {
@@ -0,0 +1,16 @@
// See also KT-7186 and forEachSafe.kt
// Custom `forEach` has no contract but the lambda is inline (not crossinline) so smart cast is safe
inline fun IntArray.forEachIndexed( op: (i: Int, value: Int) -> Unit) {
for (i in 0..this.size)
op(i, this[i])
}
fun max(a: IntArray): Int? {
var maxI: Int? = null
a.forEachIndexed { i, value ->
if (maxI == null || value >= a[maxI])
maxI = i
}
return maxI
}
@@ -1,7 +1,7 @@
// FIR_IDENTICAL
// See also KT-7186
// See also KT-7186 and forEachSafe.kt
// Custom `forEach` has no contract but the lambda is inline (not crossinline) so smart cast is safe
fun IntArray.forEachIndexed( op: (i: Int, value: Int) -> Unit) {
inline fun IntArray.forEachIndexed( op: (i: Int, value: Int) -> Unit) {
for (i in 0..this.size)
op(i, this[i])
}
@@ -1,4 +1,4 @@
package
public fun max(/*0*/ a: kotlin.IntArray): kotlin.Int?
public fun kotlin.IntArray.forEachIndexed(/*0*/ op: (i: kotlin.Int, value: kotlin.Int) -> kotlin.Unit): kotlin.Unit
public inline fun kotlin.IntArray.forEachIndexed(/*0*/ op: (i: kotlin.Int, value: kotlin.Int) -> kotlin.Unit): kotlin.Unit