From 75d2757d3c1ddf692ea7fa45c001cce7424bbfdc Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Tue, 28 Sep 2021 15:08:57 +0500 Subject: [PATCH] [K/N][IR] Fix for https://youtrack.jetbrains.com/issue/KT-43210 --- .../konan/lower/InitializersLowering.kt | 48 ++++++++++--------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InitializersLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InitializersLowering.kt index d61c67edbd1..81d92be35ba 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InitializersLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InitializersLowering.kt @@ -39,6 +39,7 @@ internal class InitializersLowering(val context: CommonBackendContext) : ClassLo private inner class InitializersTransformer(val irClass: IrClass) { val initializers = mutableListOf() + val constInitializers = mutableListOf() fun lowerInitializers() { collectAndRemoveInitializers() @@ -65,30 +66,29 @@ internal class InitializersLowering(val context: CommonBackendContext) : ClassLo val startOffset = initializer.startOffset val endOffset = initializer.endOffset val initExpression = initializer.expression - initializers.add(IrBlockImpl(startOffset, endOffset, - context.irBuiltIns.unitType, - IrStatementOrigin.INITIALIZE_FIELD, - listOf( - IrSetFieldImpl(startOffset, endOffset, declaration.symbol, - IrGetValueImpl( - startOffset, endOffset, - irClass.thisReceiver!!.type, irClass.thisReceiver!!.symbol - ), - initExpression, - context.irBuiltIns.unitType, - IrStatementOrigin.INITIALIZE_FIELD))) + val isConst = declaration.correspondingPropertySymbol?.owner?.isConst == true + if (isConst) + require(initExpression is IrConst<*>) { "Const val can only be initialized with a const: ${declaration.render()}" } + (if (isConst) constInitializers else initializers).add( + IrBlockImpl(startOffset, endOffset, + context.irBuiltIns.unitType, + IrStatementOrigin.INITIALIZE_FIELD, + listOf( + IrSetFieldImpl(startOffset, endOffset, declaration.symbol, + IrGetValueImpl( + startOffset, endOffset, + irClass.thisReceiver!!.type, irClass.thisReceiver!!.symbol + ), + initExpression, + context.irBuiltIns.unitType, + IrStatementOrigin.INITIALIZE_FIELD))) ) // We shall keep initializer for constants for compile-time instantiation. // We suppose that if the property is const, then its initializer is IrConst. // If this requirement isn't satisfied, then PropertyAccessorInlineLowering can fail. - declaration.initializer = - if (initExpression is IrConst<*> && - declaration.correspondingPropertySymbol?.owner?.isConst == true) { - IrExpressionBodyImpl(initExpression.shallowCopy()) - } else { - null - } + declaration.initializer = if (isConst) IrExpressionBodyImpl(initExpression.shallowCopy()) else null + return declaration } }) @@ -104,6 +104,7 @@ internal class InitializersLowering(val context: CommonBackendContext) : ClassLo if (irClass.declarations.any { it is IrConstructor && it.isPrimary }) return null // Place initializers in the primary constructor. + val allInitializers = constInitializers + initializers val startOffset = irClass.startOffset val endOffset = irClass.endOffset val initializeFun = @@ -129,10 +130,10 @@ internal class InitializersLowering(val context: CommonBackendContext) : ClassLo createDispatchReceiverParameter() - body = IrBlockBodyImpl(startOffset, endOffset, initializers) + body = IrBlockBodyImpl(startOffset, endOffset, allInitializers) } - for (initializer in initializers) { + for (initializer in allInitializers) { initializer.transformChildrenVoid(object : IrElementTransformerVoid() { override fun visitGetValue(expression: IrGetValue): IrExpression { if (expression.symbol == irClass.thisReceiver!!.symbol) { @@ -169,10 +170,11 @@ internal class InitializersLowering(val context: CommonBackendContext) : ClassLo when { it is IrInstanceInitializerCall -> { if (initializeMethodSymbol == null) { + val allInitializers = constInitializers + initializers assert(declaration.isPrimary) - for (initializer in initializers) + for (initializer in allInitializers) initializer.setDeclarationsParent(declaration) - initializers + allInitializers } else { val startOffset = it.startOffset val endOffset = it.endOffset