diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt index c581373c03f..d0681083c7a 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt @@ -25,7 +25,6 @@ import org.jetbrains.kotlin.ir.builders.irGet import org.jetbrains.kotlin.ir.builders.irTemporary import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrDynamicOperatorExpressionImpl -import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl import org.jetbrains.kotlin.ir.util.referenceFunction import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* @@ -39,7 +38,6 @@ import org.jetbrains.kotlin.resolve.PropertyImportedFromObject import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic -import org.jetbrains.kotlin.resolve.scopes.receivers.ThisClassReceiver import org.jetbrains.kotlin.types.KotlinType class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) { @@ -277,16 +275,10 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen isAssignmentReceiver = isAssignmentStatement ) ) - isValInitializationInConstructor(descriptor, resolvedCall) -> { - val thisClass = getThisClass() - val thisAsReceiverParameter = thisClass.thisAsReceiverParameter - val thisType = thisAsReceiverParameter.type.toIrType() - val irThis = IrGetValueImpl( - ktLeft.startOffsetSkippingComments, ktLeft.endOffset, - thisType, - context.symbolTable.referenceValueParameter(thisAsReceiverParameter) - ) - createBackingFieldLValue(ktLeft, descriptor, RematerializableValue(irThis), null) + origin == IrStatementOrigin.EQ && !descriptor.isVar -> { + // An assignment to a val property can only be its initialization in the constructor. + val receiver = resolvedCall.dispatchReceiver ?: descriptor.dispatchReceiverParameter?.value + createBackingFieldLValue(ktLeft, descriptor, statementGenerator.generateReceiverOrNull(ktLeft, receiver), null) } else -> { val propertyReceiver = statementGenerator.generateCallReceiver( @@ -356,12 +348,6 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen ) } - private fun isValInitializationInConstructor(descriptor: PropertyDescriptor, resolvedCall: ResolvedCall<*>): Boolean = - !descriptor.isVar && - descriptor.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE && - statementGenerator.scopeOwner.let { it is ConstructorDescriptor || it is ClassDescriptor } && - resolvedCall.dispatchReceiver is ThisClassReceiver - private fun getThisClass(): ClassDescriptor { val scopeOwner = statementGenerator.scopeOwner return when (scopeOwner) { diff --git a/compiler/testData/codegen/boxInline/contracts/propertyInitialization.kt b/compiler/testData/codegen/boxInline/contracts/propertyInitialization.kt index 86ae6f5e4b4..73c3b13bc34 100644 --- a/compiler/testData/codegen/boxInline/contracts/propertyInitialization.kt +++ b/compiler/testData/codegen/boxInline/contracts/propertyInitialization.kt @@ -1,6 +1,5 @@ // !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts -// IGNORE_BACKEND: JVM_IR, JS_IR, NATIVE -// IGNORE_BACKEND_MULTI_MODULE: JVM_IR +// IGNORE_BACKEND: NATIVE // FILE: 1.kt diff --git a/compiler/testData/ir/irText/classes/initVal.kt b/compiler/testData/ir/irText/classes/initVal.kt index 5b47f01e4a6..f5b4b27a0c6 100644 --- a/compiler/testData/ir/irText/classes/initVal.kt +++ b/compiler/testData/ir/irText/classes/initVal.kt @@ -12,3 +12,11 @@ class TestInitValInInitBlock { } } +class TestInitValInLambdaCalledOnce { + val x: Int + init { + 1.run { + x = 0 + } + } +} diff --git a/compiler/testData/ir/irText/classes/initVal.txt b/compiler/testData/ir/irText/classes/initVal.txt index 688c1dcc903..39dbe3d6f62 100644 --- a/compiler/testData/ir/irText/classes/initVal.txt +++ b/compiler/testData/ir/irText/classes/initVal.txt @@ -93,3 +93,44 @@ FILE fqName: fileName:/initVal.kt overridden: public open fun toString (): kotlin.String declared in kotlin.Any $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS CLASS name:TestInitValInLambdaCalledOnce modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.TestInitValInLambdaCalledOnce + CONSTRUCTOR visibility:public <> () returnType:.TestInitValInLambdaCalledOnce [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:TestInitValInLambdaCalledOnce modality:FINAL visibility:public superTypes:[kotlin.Any]' + PROPERTY name:x visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private [final] + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.TestInitValInLambdaCalledOnce) returnType:kotlin.Int + correspondingProperty: PROPERTY name:x visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.TestInitValInLambdaCalledOnce + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Int declared in .TestInitValInLambdaCalledOnce' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR ': .TestInitValInLambdaCalledOnce declared in .TestInitValInLambdaCalledOnce.' type=.TestInitValInLambdaCalledOnce origin=null + ANONYMOUS_INITIALIZER isStatic=false + BLOCK_BODY + CALL 'public final fun run (block: @[ExtensionFunctionType] kotlin.Function1): R of kotlin.run [inline] declared in kotlin' type=kotlin.Unit origin=null + : kotlin.Int + : kotlin.Unit + $receiver: CONST Int type=kotlin.Int value=1 + block: FUN_EXPR type=@[ExtensionFunctionType] kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> ($receiver:kotlin.Int) returnType:kotlin.Unit + $receiver: VALUE_PARAMETER name: type:kotlin.Int + BLOCK_BODY + SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private [final]' type=kotlin.Unit origin=null + receiver: GET_VAR ': .TestInitValInLambdaCalledOnce declared in .TestInitValInLambdaCalledOnce' type=.TestInitValInLambdaCalledOnce origin=null + value: CONST Int type=kotlin.Int value=0 + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any