Fixed bug in inliner + test
This commit is contained in:
+12
-2
@@ -275,6 +275,11 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
|
|||||||
if (irCallableReference !is IrCallableReference) return false // Second statement of the block must be CallableReference.
|
if (irCallableReference !is IrCallableReference) return false // Second statement of the block must be CallableReference.
|
||||||
return true // The expression represents lambda.
|
return true // The expression represents lambda.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val isImmutableVariableLoad: Boolean
|
||||||
|
get() = argumentExpression.let {
|
||||||
|
it is IrGetValue && !it.descriptor.let { it is VariableDescriptor && it.isVar }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
@@ -366,8 +371,13 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
|
|||||||
parameterToArgumentOld.forEach {
|
parameterToArgumentOld.forEach {
|
||||||
val parameterDescriptor = it.parameterDescriptor
|
val parameterDescriptor = it.parameterDescriptor
|
||||||
|
|
||||||
if (it.isInlinableLambda || it.argumentExpression is IrGetValue) { // If argument is inlinable lambda. IrGetValue is skipped because of recursive inline.
|
/*
|
||||||
substituteMap[parameterDescriptor] = it.argumentExpression // Associate parameter with lambda argument.
|
* We need to create temporary variable for each argument except inlinable lambdas.
|
||||||
|
* For simplicity and to produce simpler IR we don't create temporaries for every immutable variable,
|
||||||
|
* not only for those referring to inlinable lambdas.
|
||||||
|
*/
|
||||||
|
if (it.isInlinableLambda || it.isImmutableVariableLoad) {
|
||||||
|
substituteMap[parameterDescriptor] = it.argumentExpression
|
||||||
return@forEach
|
return@forEach
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2373,6 +2373,11 @@ task inline_returnLocalClassFromBlock(type: RunKonanTest) {
|
|||||||
source = "codegen/inline/returnLocalClassFromBlock.kt"
|
source = "codegen/inline/returnLocalClassFromBlock.kt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task inline_changingCapturedLocal(type: RunKonanTest) {
|
||||||
|
goldValue = "OK\n"
|
||||||
|
source = "codegen/inline/changingCapturedLocal.kt"
|
||||||
|
}
|
||||||
|
|
||||||
task deserialized_inline0(type: RunKonanTest) {
|
task deserialized_inline0(type: RunKonanTest) {
|
||||||
source = "serialization/deserialized_inline0.kt"
|
source = "serialization/deserialized_inline0.kt"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package codegen.inline.changingCapturedLocal
|
||||||
|
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
var log = ""
|
||||||
|
|
||||||
|
inline fun foo(x: Int, action: (Int) -> Unit) = action(x)
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var x = 23
|
||||||
|
foo(x) {
|
||||||
|
log += "$it;"
|
||||||
|
x++
|
||||||
|
log += "$it;"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (log != "23;23;") return "fail1: $log"
|
||||||
|
if (x != 24) return "fail2: $x"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun runTest() {
|
||||||
|
println(box())
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user