FIR CFG: do not assume all arguments to inline funs are called in place
Only values for non-noinline, non-crossinline, functional type parameters qualify.
This commit is contained in:
+55
@@ -0,0 +1,55 @@
|
||||
FILE: inlineLambdasAreInplace.kt
|
||||
public final inline fun callsInPlaceInline(x: R|() -> kotlin/Unit|): R|kotlin/Unit| {
|
||||
^callsInPlaceInline R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
|
||||
}
|
||||
public final inline fun <T> any(x: R|T|): R|T| {
|
||||
^any R|<local>/x|
|
||||
}
|
||||
public final inline fun noinline(noinline x: R|() -> kotlin/Unit|): R|() -> kotlin/Unit| {
|
||||
^noinline R|<local>/x|
|
||||
}
|
||||
public final inline fun crossinline(crossinline x: R|() -> kotlin/Unit|): R|() -> kotlin/Unit| {
|
||||
^crossinline fun <anonymous>(): R|kotlin/Unit| <inline=Unknown> {
|
||||
R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
|
||||
}
|
||||
|
||||
}
|
||||
public final fun testInline(): R|kotlin/Unit| {
|
||||
lvar x: R|kotlin/String?| = Null(null)
|
||||
R|/callsInPlaceInline|(<L> = callsInPlaceInline@fun <anonymous>(): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
|
||||
R|<local>/x| = Null(null)
|
||||
}
|
||||
)
|
||||
R|<local>/x| = String()
|
||||
R|<local>/x|.R|kotlin/String.length|
|
||||
}
|
||||
public final fun testGeneric(): R|kotlin/Unit| {
|
||||
lvar x: R|kotlin/String?| = String()
|
||||
lval lambda: R|() -> kotlin/Unit| = R|/any|<R|() -> kotlin/Unit|>(<L> = any@fun <anonymous>(): R|kotlin/Unit| <inline=Inline> {
|
||||
R|<local>/x| = Null(null)
|
||||
}
|
||||
)
|
||||
R|<local>/x| = String()
|
||||
R|<local>/lambda|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
|
||||
R|<local>/x|.<Inapplicable(UNSTABLE_SMARTCAST): kotlin/String.length>#
|
||||
}
|
||||
public final fun testNoinline(): R|kotlin/Unit| {
|
||||
lvar x: R|kotlin/String?| = String()
|
||||
lval lambda: R|() -> kotlin/Unit| = R|/noinline|(<L> = noinline@fun <anonymous>(): R|kotlin/Unit| <inline=NoInline> {
|
||||
R|<local>/x| = Null(null)
|
||||
}
|
||||
)
|
||||
R|<local>/x| = String()
|
||||
R|<local>/lambda|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
|
||||
R|<local>/x|.<Inapplicable(UNSTABLE_SMARTCAST): kotlin/String.length>#
|
||||
}
|
||||
public final fun testCrossinline(): R|kotlin/Unit| {
|
||||
lvar x: R|kotlin/String?| = String()
|
||||
lval lambda: R|() -> kotlin/Unit| = R|/crossinline|(<L> = crossinline@fun <anonymous>(): R|kotlin/Unit| <inline=CrossInline> {
|
||||
R|<local>/x| = Null(null)
|
||||
}
|
||||
)
|
||||
R|<local>/x| = String()
|
||||
R|<local>/lambda|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
|
||||
R|<local>/x|.<Inapplicable(UNSTABLE_SMARTCAST): kotlin/String.length>#
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
inline fun callsInPlaceInline(x: () -> Unit) = x()
|
||||
|
||||
<!NOTHING_TO_INLINE!>inline<!> fun <T> any(x: T) = x
|
||||
|
||||
<!NOTHING_TO_INLINE!>inline<!> fun noinline(noinline x: () -> Unit) = x
|
||||
|
||||
inline fun crossinline(crossinline x: () -> Unit) = { x() }
|
||||
|
||||
fun testInline() {
|
||||
var x: String? = null
|
||||
callsInPlaceInline { x = null }
|
||||
x = ""
|
||||
x.length // ok
|
||||
}
|
||||
|
||||
fun testGeneric() {
|
||||
var x: String? = ""
|
||||
val lambda = any { x = null }
|
||||
x = ""
|
||||
lambda()
|
||||
<!SMARTCAST_IMPOSSIBLE!>x<!>.length // bad
|
||||
}
|
||||
|
||||
fun testNoinline() {
|
||||
var x: String? = ""
|
||||
val lambda = noinline { x = null }
|
||||
x = ""
|
||||
lambda()
|
||||
<!SMARTCAST_IMPOSSIBLE!>x<!>.length // bad
|
||||
}
|
||||
|
||||
fun testCrossinline() {
|
||||
var x: String? = ""
|
||||
val lambda = crossinline { x = null }
|
||||
x = ""
|
||||
lambda()
|
||||
<!SMARTCAST_IMPOSSIBLE!>x<!>.length // bad
|
||||
}
|
||||
@@ -50,13 +50,11 @@ digraph postponedLambdas_kt {
|
||||
8 -> {9 13 10};
|
||||
8 -> {13} [style=dashed];
|
||||
9 -> {10};
|
||||
9 -> {8} [color=green style=dashed];
|
||||
10 -> {11};
|
||||
11 -> {12};
|
||||
13 -> {14};
|
||||
14 -> {15};
|
||||
15 -> {16};
|
||||
16 -> {17};
|
||||
17 -> {9};
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ FILE: postponedLambdas.kt
|
||||
public final inline fun foo(vararg x: R|kotlin/Array<out kotlin/Any>|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun test(a: R|kotlin/Any|, b: R|kotlin/Any|, c: R|kotlin/Any|): R|kotlin/Unit| {
|
||||
R|/foo|(vararg(R|<local>/a|, foo@fun <anonymous>(): R|kotlin/String| <inline=Unknown, kind=UNKNOWN> {
|
||||
R|/foo|(vararg(R|<local>/a|, foo@fun <anonymous>(): R|kotlin/String| <inline=Unknown> {
|
||||
^ String()
|
||||
}
|
||||
, R|<local>/b|))
|
||||
|
||||
+2
-2
@@ -47,13 +47,13 @@ FILE: lambdaWithoutExpectedType.kt
|
||||
public abstract interface XdIssueFolder : R|kotlin/Any| {
|
||||
}
|
||||
public final fun test(): R|kotlin/Unit| {
|
||||
lval array: R|kotlin/Array<kotlin/Any>| = R|kotlin/arrayOf|<R|kotlin/Any|>(vararg(String(Project), arrayOf@fun <anonymous>(): R|XdProject?| <inline=Unknown, kind=UNKNOWN> {
|
||||
lval array: R|kotlin/Array<kotlin/Any>| = R|kotlin/arrayOf|<R|kotlin/Any|>(vararg(String(Project), arrayOf@fun <anonymous>(): R|XdProject?| <inline=Unknown> {
|
||||
^ Q|XdProject|.R|/filter|<R|XdProject|>(<L> = filter@fun R|FilteringContext|.<anonymous>(it: R|XdProject|): R|XdSearchingNode| <inline=NoInline> {
|
||||
^ (this@R|special/anonymous|, R|<local>/it|.R|/XdProject.name|).R|/FilteringContext.eq|<R|kotlin/String|>(String(foo))
|
||||
}
|
||||
).R|/firstOrNull|<R|XdProject|>()
|
||||
}
|
||||
, arrayOf@fun <anonymous>(<unused var>: R|XdIssue|, <unused var>: R|XdIssueFolder|): R|kotlin/Unit| <inline=Unknown, kind=UNKNOWN> {
|
||||
, arrayOf@fun <anonymous>(<unused var>: R|XdIssue|, <unused var>: R|XdIssueFolder|): R|kotlin/Unit| <inline=Unknown> {
|
||||
^@arrayOf Unit
|
||||
}
|
||||
))
|
||||
|
||||
Vendored
+1
-1
@@ -19,7 +19,7 @@ FILE: delegateTypeMismatch.kt
|
||||
public get(): R|kotlin/Boolean|
|
||||
|
||||
private final fun <T> property(initialValue: R|T|): R|kotlin/properties/ReadWriteProperty<A, T>| {
|
||||
^property Q|kotlin/properties/Delegates|.R|kotlin/properties/Delegates.vetoable|<R|T|>(R|<local>/initialValue|, <L> = vetoable@fun <anonymous>(<unused var>: R|@R|kotlin/ParameterName|(name = String(property)) kotlin/reflect/KProperty<*>|, <unused var>: R|T|, <unused var>: R|T|): R|kotlin/Boolean| <inline=CrossInline, kind=UNKNOWN> {
|
||||
^property Q|kotlin/properties/Delegates|.R|kotlin/properties/Delegates.vetoable|<R|T|>(R|<local>/initialValue|, <L> = vetoable@fun <anonymous>(<unused var>: R|@R|kotlin/ParameterName|(name = String(property)) kotlin/reflect/KProperty<*>|, <unused var>: R|T|, <unused var>: R|T|): R|kotlin/Boolean| <inline=CrossInline> {
|
||||
^ when () {
|
||||
this@R|/A|.R|/A.isLocked| -> {
|
||||
throw R|java/lang/IllegalStateException.IllegalStateException|(String(Cannot modify readonly DescriptorRendererOptions))
|
||||
|
||||
Vendored
+1
-5
@@ -43,14 +43,12 @@ digraph plusAssignWithLambdaInRhs_kt {
|
||||
7 -> {8 12 9} [style=dotted];
|
||||
7 -> {12} [style=dashed];
|
||||
8 -> {9} [style=dotted];
|
||||
8 -> {7} [color=green style=dotted];
|
||||
9 -> {10} [style=dotted];
|
||||
10 -> {11} [style=dotted];
|
||||
12 -> {13} [style=dotted];
|
||||
13 -> {14} [style=dotted];
|
||||
14 -> {15} [style=dotted];
|
||||
15 -> {16} [style=dotted];
|
||||
16 -> {8} [style=dotted];
|
||||
|
||||
subgraph cluster_4 {
|
||||
color=red
|
||||
@@ -120,7 +118,7 @@ digraph plusAssignWithLambdaInRhs_kt {
|
||||
31 [label="Postponed exit from lambda"];
|
||||
32 [label="Function call: R|/A.A|<R|T|>(...)" style="filled" fillcolor=yellow];
|
||||
33 [label="Jump: ^postpone R|/A.A|<R|T|>(<L> = A@fun <anonymous>(resolve: R|(T) -> kotlin/Unit|): R|kotlin/Unit| <inline=NoInline> {
|
||||
R|<local>/queue|.R|kotlin/collections/plusAssign|<R|() -> kotlin/Unit|>(A@fun <anonymous>(): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
|
||||
R|<local>/queue|.R|kotlin/collections/plusAssign|<R|() -> kotlin/Unit|>(A@fun <anonymous>(): R|kotlin/Unit| <inline=Inline> {
|
||||
R|<local>/resolve|.R|SubstitutionOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(R|<local>/computation|.R|SubstitutionOverride<kotlin/Function0.invoke: R|T|>|())
|
||||
}
|
||||
)
|
||||
@@ -149,7 +147,6 @@ digraph plusAssignWithLambdaInRhs_kt {
|
||||
40 -> {41 45 42};
|
||||
40 -> {45} [style=dashed];
|
||||
41 -> {42};
|
||||
41 -> {40} [color=green style=dashed];
|
||||
42 -> {43};
|
||||
43 -> {44};
|
||||
45 -> {46};
|
||||
@@ -157,6 +154,5 @@ digraph plusAssignWithLambdaInRhs_kt {
|
||||
47 -> {48};
|
||||
48 -> {49};
|
||||
49 -> {50};
|
||||
50 -> {41};
|
||||
|
||||
}
|
||||
|
||||
Vendored
+2
-2
@@ -1,7 +1,7 @@
|
||||
FILE: plusAssignWithLambdaInRhs.kt
|
||||
public final fun test(): R|kotlin/Unit| {
|
||||
lval list: R|kotlin/collections/MutableList<kotlin/Function1<kotlin/String, kotlin/String>>| = Null(null)!!
|
||||
R|<local>/list|.R|kotlin/collections/plusAssign|<R|(kotlin/String) -> kotlin/String|>(fun <anonymous>(it: R|kotlin/String|): R|kotlin/String| <inline=Inline, kind=UNKNOWN> {
|
||||
R|<local>/list|.R|kotlin/collections/plusAssign|<R|(kotlin/String) -> kotlin/String|>(fun <anonymous>(it: R|kotlin/String|): R|kotlin/String| <inline=Inline> {
|
||||
^ R|<local>/it|
|
||||
}
|
||||
)
|
||||
@@ -18,7 +18,7 @@ FILE: plusAssignWithLambdaInRhs.kt
|
||||
public final fun <T> postpone(computation: R|() -> T|): R|A<T>| {
|
||||
lval queue: R|kotlin/collections/MutableList<kotlin/Function0<kotlin/Unit>>| = R|kotlin/collections/mutableListOf|<R|() -> kotlin/Unit|>()
|
||||
^postpone R|/A.A|<R|T|>(<L> = A@fun <anonymous>(resolve: R|(T) -> kotlin/Unit|): R|kotlin/Unit| <inline=NoInline> {
|
||||
R|<local>/queue|.R|kotlin/collections/plusAssign|<R|() -> kotlin/Unit|>(A@fun <anonymous>(): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
|
||||
R|<local>/queue|.R|kotlin/collections/plusAssign|<R|() -> kotlin/Unit|>(A@fun <anonymous>(): R|kotlin/Unit| <inline=Inline> {
|
||||
R|<local>/resolve|.R|SubstitutionOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(R|<local>/computation|.R|SubstitutionOverride<kotlin/Function0.invoke: R|T|>|())
|
||||
}
|
||||
)
|
||||
|
||||
Vendored
+1
-1
@@ -28,7 +28,7 @@ FILE: buildListLazy.kt
|
||||
this@R|special/anonymous|.R|kotlin/collections/plusAssign|<R|NameAndSafeValue|>(R|/NameAndSafeValue.NameAndSafeValue|(R|<local>/name|, R|<local>/value|))
|
||||
}
|
||||
)
|
||||
this@R|special/anonymous|.R|kotlin/collections/sortBy|<R|NameAndSafeValue|, R|kotlin/String|>(<L> = sortBy@fun <anonymous>(it: R|NameAndSafeValue|): R|kotlin/String?| <inline=CrossInline, kind=UNKNOWN> {
|
||||
this@R|special/anonymous|.R|kotlin/collections/sortBy|<R|NameAndSafeValue|, R|kotlin/String|>(<L> = sortBy@fun <anonymous>(it: R|NameAndSafeValue|): R|kotlin/String?| <inline=CrossInline> {
|
||||
^ R|<local>/it|.R|/NameAndSafeValue.name|
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user