From db50381bc91970506b73cc7f07ceda526da006a0 Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Thu, 6 Apr 2017 18:55:54 +0300 Subject: [PATCH] Inline: set correct containing declaration + some fixes 1. Containing declaration can be computed as parent from the IR. 2. Sometimes we need to substitute FunctionDescriptor which is defined inside an inline function call but nevertheless leaks to the outside: public inline fun T.myLet(f: (T) -> R): R = f(this) interface foo { fun bar(): String } fun box(): String { val baz = "OK".myLet { object : foo { override fun bar() = it } } return baz.bar() } --- .../common/DeepCopyIrTreeWithDescriptoros.kt | 135 ++++++++------- .../IrElementTransformerVoidWithContext.kt | 158 +++++++++++++++--- .../backend/konan/lower/FunctionInlining.kt | 36 +--- .../backend/konan/lower/InnerClassLowering.kt | 2 +- 4 files changed, 217 insertions(+), 114 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDescriptoros.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDescriptoros.kt index 3bb0e1f1447..f58009596b7 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDescriptoros.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDescriptoros.kt @@ -23,20 +23,20 @@ import org.jetbrains.kotlin.backend.konan.ir.IrInlineFunctionBody import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.impl.* import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.declarations.impl.* -import org.jetbrains.kotlin.ir.declarations.IrClass -import org.jetbrains.kotlin.ir.declarations.IrFunction -import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl import org.jetbrains.kotlin.ir.expressions.* -import org.jetbrains.kotlin.ir.expressions.impl.* +import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrCallableReferenceImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl import org.jetbrains.kotlin.ir.util.DeepCopyIrTree -import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid +import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid +import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeProjectionImpl @@ -44,7 +44,7 @@ import org.jetbrains.kotlin.types.TypeSubstitutor import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.typeUtil.makeNullable -internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, typeArgsMap: Map ?, val context: Context) { +internal class DeepCopyIrTreeWithDescriptors(val targetScope: ScopeWithIr, typeArgsMap: Map ?, val context: Context) { private val descriptorSubstituteMap: MutableMap = mutableMapOf() private var typeSubstitutor = createTypeSubstitutor(typeArgsMap) @@ -58,20 +58,64 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, typ inlinedFunctionName = functionName descriptorSubstituteMap.clear() irElement.acceptChildrenVoid(DescriptorCollector()) + // Transform calls to object that might be returned from inline function call. + targetScope.irElement.transformChildrenVoid(descriptorSubstitutorForExternalScope) return irElement.accept(InlineCopyIr(), null) } //-------------------------------------------------------------------------// - inner class DescriptorCollector: IrElementVisitorVoid { + val descriptorSubstitutorForExternalScope = object : IrElementTransformerVoid() { - override fun visitClass(declaration: IrClass) { + override fun visitCall(expression: IrCall): IrExpression { + val oldExpression = super.visitCall(expression) as IrCall + + return when (oldExpression) { + is IrCallImpl -> copyIrCallImpl(oldExpression) + else -> oldExpression + } + } + } + + private fun copyIrCallImpl(oldExpression: IrCallImpl): IrCallImpl { + val oldDescriptor = oldExpression.descriptor + val newDescriptor = descriptorSubstituteMap.getOrDefault(oldDescriptor.original, + oldDescriptor) as FunctionDescriptor + + val oldSuperQualifier = oldExpression.superQualifier + val newSuperQualifier = oldSuperQualifier?.let { (descriptorSubstituteMap[it] ?: it) as ClassDescriptor } + + val newExpression = IrCallImpl( + oldExpression.startOffset, + oldExpression.endOffset, + substituteType(oldExpression.type)!!, + newDescriptor, + substituteTypeArguments(oldExpression.typeArguments), + oldExpression.origin, + newSuperQualifier + ).apply { + oldExpression.descriptor.valueParameters.forEach { + val valueArgument = oldExpression.getValueArgument(it) + putValueArgument(it.index, valueArgument) + } + extensionReceiver = oldExpression.extensionReceiver + dispatchReceiver = oldExpression.dispatchReceiver + } + + return newExpression + } + + //-------------------------------------------------------------------------// + + inner class DescriptorCollector: IrElementVisitorVoidWithContext() { + + override fun visitClassNew(declaration: IrClass) { val oldDescriptor = declaration.descriptor val newDescriptor = copyClassDescriptor(oldDescriptor) descriptorSubstituteMap[oldDescriptor] = newDescriptor descriptorSubstituteMap[oldDescriptor.thisAsReceiverParameter] = newDescriptor.thisAsReceiverParameter - super.visitClass(declaration) + super.visitClassNew(declaration) val constructors = oldDescriptor.constructors.map { oldConstructorDescriptor -> descriptorSubstituteMap[oldConstructorDescriptor] as ClassConstructorDescriptor @@ -110,30 +154,30 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, typ } } - override fun visitProperty(declaration: IrProperty) { + override fun visitPropertyNew(declaration: IrProperty) { copyPropertyOrField(declaration.descriptor) - super.visitProperty(declaration) + super.visitPropertyNew(declaration) } - override fun visitField(declaration: IrField) { + override fun visitFieldNew(declaration: IrField) { val oldDescriptor = declaration.descriptor if (descriptorSubstituteMap[oldDescriptor] == null) { // A field without a property or a field of a delegated property. copyPropertyOrField(oldDescriptor) } - super.visitField(declaration) + super.visitFieldNew(declaration) } //---------------------------------------------------------------------// - override fun visitFunction(declaration: IrFunction) { + override fun visitFunctionNew(declaration: IrFunction) { val oldDescriptor = declaration.descriptor if (oldDescriptor !is PropertyAccessorDescriptor) { // Property accessors are copied along with their property. val newDescriptor = copyFunctionDescriptor(oldDescriptor) descriptorSubstituteMap[oldDescriptor] = newDescriptor } - super.visitFunction(declaration) + super.visitFunctionNew(declaration) } //---------------------------------------------------------------------// @@ -143,7 +187,8 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, typ val descriptor = expression.descriptor as FunctionDescriptor if (descriptor.isFunctionInvoke) { val oldDescriptor = descriptor as SimpleFunctionDescriptor - val containingDeclaration = targetFunction.descriptor + // Containing declaration for value parameter is not that important - other lowerings should not rely on it. + val containingDeclaration = (targetScope.scope.scopeOwner as? CallableDescriptor) ?: oldDescriptor val newReturnType = substituteType(oldDescriptor.returnType)!! val newValueParameters = copyValueParameters(oldDescriptor.valueParameters, containingDeclaration) val newDescriptor = oldDescriptor.newCopyBuilder().apply { @@ -163,7 +208,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, typ val oldDescriptor = declaration.descriptor val newDescriptor = IrTemporaryVariableDescriptorImpl( - targetFunction.descriptor, + targetScope.scope.scopeOwner, generateName(oldDescriptor.name), substituteType(oldDescriptor.type)!!, oldDescriptor.isVar) @@ -181,7 +226,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, typ private fun generateName(name: Name): Name { - val containingName = targetFunction.descriptor.name.toString() // Name of inline target (function we inline in) + val containingName = targetScope.scope.scopeOwner.name.toString() // Name of inline target (function we inline in) val declarationName = name.toString() // Name of declaration val indexStr = (nameIndex++).toString() // Unique for inline target index return Name.identifier(containingName + "_" + inlinedFunctionName + "_" + declarationName + "_" + indexStr) @@ -202,8 +247,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, typ private fun copySimpleFunctionDescriptor(oldDescriptor: SimpleFunctionDescriptor) : FunctionDescriptor { - val oldContainingDeclaration = oldDescriptor.containingDeclaration // TODO should target function to be containing declaration - val newContainingDeclaration = descriptorSubstituteMap[oldContainingDeclaration] ?: targetFunction.descriptor + val newContainingDeclaration = parentScope?.let { descriptorSubstituteMap[it.scope.scopeOwner] } ?: targetScope.scope.scopeOwner val newDescriptor = SimpleFunctionDescriptorImpl.create( newContainingDeclaration, @@ -239,10 +283,9 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, typ private fun copyConstructorDescriptor(oldDescriptor: ConstructorDescriptor) : FunctionDescriptor { - val oldContainingDeclaration = oldDescriptor.containingDeclaration - val containingDeclaration = descriptorSubstituteMap[oldContainingDeclaration] + val containingDeclaration = parentScope?.let { descriptorSubstituteMap[it.scope.scopeOwner] } as ClassDescriptor val newDescriptor = ClassConstructorDescriptorImpl.create( - containingDeclaration as ClassDescriptor, + containingDeclaration, oldDescriptor.annotations, oldDescriptor.isPrimary, oldDescriptor.source @@ -270,8 +313,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, typ //---------------------------------------------------------------------// private fun copyPropertyDescriptor(oldDescriptor: PropertyDescriptor): PropertyDescriptor { - val oldContainingDeclaration = oldDescriptor.containingDeclaration - val memberOwner = descriptorSubstituteMap[oldContainingDeclaration] as ClassDescriptor + val memberOwner = currentClass?.let { descriptorSubstituteMap[it.scope.scopeOwner] } as ClassDescriptor val newDescriptor = PropertyDescriptorImpl.create( memberOwner, oldDescriptor.annotations, @@ -349,9 +391,14 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, typ val oldSuperClass = oldDescriptor.getSuperClassOrAny() val newSuperClass = descriptorSubstituteMap.getOrDefault(oldSuperClass, oldSuperClass) as ClassDescriptor + val newContainingDeclaration = parentScope?.let { descriptorSubstituteMap[it.scope.scopeOwner] } ?: targetScope.scope.scopeOwner + val newName = if (DescriptorUtils.isAnonymousObject(oldDescriptor)) // Anonymous objects are identified by their name. + oldDescriptor.name // We need to preserve it for LocalDeclarationsLowering. + else + generateName(oldDescriptor.name) return ClassDescriptorImpl( - targetFunction.descriptor, - generateName(oldDescriptor.name), + newContainingDeclaration, + newName, oldDescriptor.modality, oldDescriptor.kind, listOf(newSuperClass.defaultType), @@ -401,35 +448,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, typ val oldExpression = super.visitCall(expression) as IrCall if (oldExpression !is IrCallImpl) return oldExpression // TODO what other kinds of call can we meet? - val oldDescriptor = oldExpression.descriptor - val newDescriptor = descriptorSubstituteMap.getOrDefault(oldDescriptor, - oldDescriptor) as FunctionDescriptor - - val oldSuperQualifier = oldExpression.superQualifier - var newSuperQualifier: ClassDescriptor? = oldSuperQualifier - if (newSuperQualifier != null) { - newSuperQualifier = descriptorSubstituteMap.getOrDefault(newSuperQualifier, - newSuperQualifier) as ClassDescriptor - } - - val newExpression = IrCallImpl( - oldExpression.startOffset, - oldExpression.endOffset, - substituteType(oldExpression.type)!!, - newDescriptor, - substituteTypeArguments(oldExpression.typeArguments), - oldExpression.origin, - newSuperQualifier - ).apply { - oldExpression.descriptor.valueParameters.forEach { - val valueArgument = oldExpression.getValueArgument(it) - putValueArgument(it.index, valueArgument) - } - extensionReceiver = oldExpression.extensionReceiver - dispatchReceiver = oldExpression.dispatchReceiver - } - - return newExpression + return copyIrCallImpl(oldExpression) } //---------------------------------------------------------------------// diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/IrElementTransformerVoidWithContext.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/IrElementTransformerVoidWithContext.kt index 2186bda8a21..b1e53315d9a 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/IrElementTransformerVoidWithContext.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/IrElementTransformerVoidWithContext.kt @@ -16,49 +16,157 @@ package org.jetbrains.kotlin.backend.common -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement -import org.jetbrains.kotlin.ir.declarations.IrClass -import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.builders.Scope +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid +import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid +import org.jetbrains.kotlin.descriptors.* -abstract class IrElementTransformerVoidWithContext(): IrElementTransformerVoid() { - private fun MutableList.push(element: E) = this.add(element) +private fun MutableList.push(element: E) = this.add(element) - private fun MutableList.pop() = this.removeAt(size - 1) +private fun MutableList.pop() = this.removeAt(size - 1) - private fun MutableList.peek(): E? = if (size == 0) null else this[size - 1] +private fun MutableList.peek(): E? = if (size == 0) null else this[size - 1] - private val functionsStack = mutableListOf() - private val functionDeclarationsStack = mutableListOf() - private val classesStack = mutableListOf() +internal class ScopeWithIr(val scope: Scope, val irElement: IrElement) - override final fun visitFunction(declaration: IrFunction): IrStatement { - functionsStack.push(declaration.descriptor) - functionDeclarationsStack.push(declaration) - val result = visitFunctionNew(declaration) - functionDeclarationsStack.pop() - functionsStack.pop() +abstract internal class IrElementTransformerVoidWithContext : IrElementTransformerVoid() { + + private val scopeStack = mutableListOf() + + override final fun visitFile(declaration: IrFile): IrFile { + scopeStack.push(ScopeWithIr(Scope(declaration.packageFragmentDescriptor), declaration)) + val result = visitFileNew(declaration) + scopeStack.pop() return result } override final fun visitClass(declaration: IrClass): IrStatement { - classesStack.push(declaration.descriptor) + scopeStack.push(ScopeWithIr(Scope(declaration.descriptor), declaration)) val result = visitClassNew(declaration) - classesStack.pop() + scopeStack.pop() return result } - protected val currentFunction get() = functionsStack.peek() - protected val currentFunctionDeclaration get() = functionDeclarationsStack.peek() - protected val currentClass get() = classesStack.peek() + override final fun visitProperty(declaration: IrProperty): IrStatement { + scopeStack.push(ScopeWithIr(Scope(declaration.descriptor), declaration)) + val result = visitPropertyNew(declaration) + scopeStack.pop() + return result + } - open fun visitFunctionNew(declaration: IrFunction) : IrStatement { + override final fun visitField(declaration: IrField): IrStatement { + val isDelegated = declaration.descriptor.isDelegated + if (isDelegated) scopeStack.push(ScopeWithIr(Scope(declaration.descriptor), declaration)) + val result = visitFieldNew(declaration) + if (isDelegated) scopeStack.pop() + return result + } + + override final fun visitFunction(declaration: IrFunction): IrStatement { + scopeStack.push(ScopeWithIr(Scope(declaration.descriptor), declaration)) + val result = visitFunctionNew(declaration) + scopeStack.pop() + return result + } + + protected val currentFile get() = scopeStack.lastOrNull { it.scope.scopeOwner is PackageFragmentDescriptor } + protected val currentClass get() = scopeStack.lastOrNull { it.scope.scopeOwner is ClassDescriptor } + protected val currentFunction get() = scopeStack.lastOrNull { it.scope.scopeOwner is FunctionDescriptor } + protected val currentProperty get() = scopeStack.lastOrNull { it.scope.scopeOwner is PropertyDescriptor } + protected val currentScope get() = scopeStack.peek() + protected val parentScope get() = if (scopeStack.size < 2) null else scopeStack[scopeStack.size - 2] + + fun printScopeStack() { + scopeStack.forEach { println(it.scope.scopeOwner) } + } + + open fun visitFileNew(declaration: IrFile): IrFile { + return super.visitFile(declaration) + } + + open fun visitClassNew(declaration: IrClass): IrStatement { + return super.visitClass(declaration) + } + + open fun visitFunctionNew(declaration: IrFunction): IrStatement { return super.visitFunction(declaration) } - open fun visitClassNew(declaration: IrClass) : IrStatement { - return super.visitClass(declaration) + open fun visitPropertyNew(declaration: IrProperty): IrStatement { + return super.visitProperty(declaration) + } + + open fun visitFieldNew(declaration: IrField): IrStatement { + return super.visitField(declaration) + } +} + +abstract internal class IrElementVisitorVoidWithContext : IrElementVisitorVoid { + + private val scopeStack = mutableListOf() + + override final fun visitFile(declaration: IrFile) { + scopeStack.push(ScopeWithIr(Scope(declaration.packageFragmentDescriptor), declaration)) + visitFileNew(declaration) + scopeStack.pop() + } + + override final fun visitClass(declaration: IrClass) { + scopeStack.push(ScopeWithIr(Scope(declaration.descriptor), declaration)) + visitClassNew(declaration) + scopeStack.pop() + } + + override final fun visitProperty(declaration: IrProperty) { + scopeStack.push(ScopeWithIr(Scope(declaration.descriptor), declaration)) + visitPropertyNew(declaration) + scopeStack.pop() + } + + override final fun visitField(declaration: IrField) { + val isDelegated = declaration.descriptor.isDelegated + if (isDelegated) scopeStack.push(ScopeWithIr(Scope(declaration.descriptor), declaration)) + visitFieldNew(declaration) + if (isDelegated) scopeStack.pop() + } + + override final fun visitFunction(declaration: IrFunction) { + scopeStack.push(ScopeWithIr(Scope(declaration.descriptor), declaration)) + visitFunctionNew(declaration) + scopeStack.pop() + } + + protected val currentFile get() = scopeStack.lastOrNull { it.scope.scopeOwner is PackageFragmentDescriptor } + protected val currentClass get() = scopeStack.lastOrNull { it.scope.scopeOwner is ClassDescriptor } + protected val currentFunction get() = scopeStack.lastOrNull { it.scope.scopeOwner is FunctionDescriptor } + protected val currentProperty get() = scopeStack.lastOrNull { it.scope.scopeOwner is PropertyDescriptor } + protected val currentScope get() = scopeStack.peek() + protected val parentScope get() = if (scopeStack.size < 2) null else scopeStack[scopeStack.size - 2] + + fun printScopeStack() { + scopeStack.forEach { println(it.scope.scopeOwner) } + } + + open fun visitFileNew(declaration: IrFile) { + super.visitFile(declaration) + } + + open fun visitClassNew(declaration: IrClass) { + super.visitClass(declaration) + } + + open fun visitFunctionNew(declaration: IrFunction) { + super.visitFunction(declaration) + } + + open fun visitPropertyNew(declaration: IrProperty) { + super.visitProperty(declaration) + } + + open fun visitFieldNew(declaration: IrField) { + super.visitField(declaration) } } \ No newline at end of file diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt index 8cb0cfed3b2..8cbc932720f 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.DeepCopyIrTreeWithDescriptors +import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.descriptors.isFunctionInvoke import org.jetbrains.kotlin.backend.konan.descriptors.needsInlining @@ -43,11 +44,8 @@ import org.jetbrains.kotlin.types.KotlinType //-----------------------------------------------------------------------------// -internal class FunctionInlining(val context: Context): IrElementTransformerVoid() { +internal class FunctionInlining(val context: Context): IrElementTransformerVoidWithContext() { - private var currentFile : IrFile? = null - private var currentFunction : IrFunction? = null - private var currentScope : Scope? = null private var copyWithDescriptors: DeepCopyIrTreeWithDescriptors? = null private val deserializer = DeserializerDriver(context) @@ -61,28 +59,6 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( //-------------------------------------------------------------------------// - override fun visitFile(declaration: IrFile): IrFile { - currentFile = declaration - return super.visitFile(declaration) - } - - //-------------------------------------------------------------------------// - - override fun visitProperty(declaration: IrProperty): IrStatement { - currentScope = Scope(declaration.descriptor) - return super.visitProperty(declaration) - } - - //-------------------------------------------------------------------------// - - override fun visitFunction(declaration: IrFunction): IrStatement { - currentFunction = declaration - currentScope = Scope(declaration.descriptor) - return super.visitFunction(declaration) - } - - //-------------------------------------------------------------------------// - override fun visitCall(expression: IrCall): IrExpression { val irCall = super.visitCall(expression) as IrCall val functionDescriptor = irCall.descriptor as FunctionDescriptor @@ -94,12 +70,12 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( //-------------------------------------------------------------------------// private fun createInlineFunctionBody(functionDeclaration: IrFunction, typeArgsMap: Map ?): IrInlineFunctionBody? { - functionDeclaration.transformChildrenVoid(this) // TODO recursive inline is already processed in visitCall. Check + functionDeclaration.transformChildrenVoid(this) // Process recursive inline. val originBlockBody = functionDeclaration.body if (originBlockBody == null) return null // TODO workaround - copyWithDescriptors = DeepCopyIrTreeWithDescriptors(currentFunction!!, typeArgsMap, context) + copyWithDescriptors = DeepCopyIrTreeWithDescriptors(currentScope!!, typeArgsMap, context) val functionName = functionDeclaration.descriptor.name.toString() val copyBlockBody = copyWithDescriptors!!.copy(originBlockBody, functionName) as IrBlockBody // Create copy of original function body. @@ -321,8 +297,8 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( return@forEach } - val varName = currentScope!!.scopeOwner.name.toString() + "_inline" - val newVar = currentScope!!.createTemporaryVariable(argument, varName, false) // Create new variable and init it with the parameter expression. + val varName = currentScope!!.scope.scopeOwner.name.toString() + "_inline" + val newVar = currentScope!!.scope.createTemporaryVariable(argument, varName, false) // Create new variable and init it with the parameter expression. statements.add(newVar) // Add initialization of the new variable in statement list. val getVal = IrGetValueImpl(0, 0, newVar.descriptor) // Create new IR element representing access the new variable. diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InnerClassLowering.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InnerClassLowering.kt index 430bbfd6304..723cd97da65 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InnerClassLowering.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InnerClassLowering.kt @@ -106,7 +106,7 @@ internal class InnerClassLowering(val context: Context) : ClassLoweringPass { if (implicitThisClass == classDescriptor) return expression - val constructorDescriptor = currentFunction!! as? ConstructorDescriptor + val constructorDescriptor = currentFunction!!.scope.scopeOwner as? ConstructorDescriptor val startOffset = expression.startOffset val endOffset = expression.endOffset