diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 38b73c1543f..d31d1fed313 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -13316,6 +13316,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/delegatedProperty/delegateToAnotherWithSideEffects.kt"); } + @Test + @TestMetadata("delegateToConstructorParameter.kt") + public void testDelegateToConstructorParameter() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/delegateToConstructorParameter.kt"); + } + @Test @TestMetadata("delegateToGenericJavaProperty.kt") public void testDelegateToGenericJavaProperty() throws Exception { diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt index 661e54bb70b..1b90d5696c5 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt @@ -59,7 +59,7 @@ val IrDeclaration.parentsWithSelf: Sequence get() = generateSequence(this as? IrDeclarationParent) { (it as? IrDeclaration)?.parent } val IrDeclaration.parents: Sequence - get() = parentsWithSelf.drop(1) + get() = generateSequence(parent) { (it as? IrDeclaration)?.parent } object BOUND_VALUE_PARAMETER : IrDeclarationOriginImpl("BOUND_VALUE_PARAMETER") diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceDelegationLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceDelegationLowering.kt index eede5cb8dd6..05b5295a02a 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceDelegationLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceDelegationLowering.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.jvm.lower import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.lower.createIrBuilder +import org.jetbrains.kotlin.backend.common.lower.parents import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.codegen.fileParent @@ -85,14 +86,16 @@ private class PropertyReferenceDelegationTransformer(val context: JvmBackendCont private val IrStatement.isStdlibCall: Boolean get() = this is IrCall && symbol.owner.getPackageFragment()?.fqName == StandardNames.BUILT_INS_PACKAGE_FQ_NAME - // Constants, object accesses, reads of immutable variables, and reads of immutable properties in the same file - // don't need to be cached in a field; reads of mutable properties have to be as we should ignore further assignments - // to those, and immutable properties in other files might become mutable without breaking ABI. - private fun IrExpression.canInline(currentFile: IrFile): Boolean = when (this) { - is IrGetValue -> !symbol.owner.let { it is IrVariable && it.isVar } - is IrGetField -> symbol.owner.let { it.isFinal && it.fileParent == currentFile } && receiver?.canInline(currentFile) != false - is IrCall -> symbol.owner.let { it.isFinalDefaultValGetter && it.fileParent == currentFile } && - dispatchReceiver?.canInline(currentFile) != false && extensionReceiver?.canInline(currentFile) != false + // Some receivers don't need to be stored in fields and can be reevaluated every time an accessor is called: + private fun IrExpression.canInline(visibleScopes: Set): Boolean = when (this) { + // Reads of immutable variables are stable, but value parameters of the constructor are not in scope: + is IrGetValue -> symbol.owner.let { !(it is IrVariable && it.isVar) && it.parent in visibleScopes } + // Reads of final fields of stable values are stable, but fields in other files can become non-final: + is IrGetField -> symbol.owner.let { it.isFinal && it.fileParent in visibleScopes } && receiver?.canInline(visibleScopes) != false + // Same applies to reads of properties with default getters, but non-final properties may be overridden by `var`s: + is IrCall -> symbol.owner.let { it.isFinalDefaultValGetter && it.fileParent in visibleScopes } && + dispatchReceiver?.canInline(visibleScopes) != false && extensionReceiver?.canInline(visibleScopes) != false + // Constants and singleton object accesses are always stable: else -> isTrivial() } @@ -134,7 +137,7 @@ private class PropertyReferenceDelegationTransformer(val context: JvmBackendCont val receiver = (delegate.dispatchReceiver ?: delegate.extensionReceiver) ?.transform(this@PropertyReferenceDelegationTransformer, null) - backingField = receiver?.takeIf { !it.canInline(fileParent) }?.let { + backingField = receiver?.takeIf { !it.canInline(parents.toSet()) }?.let { context.irFactory.buildField { updateFrom(oldField) name = Name.identifier("${this@transform.name}\$receiver") diff --git a/compiler/testData/codegen/box/delegatedProperty/delegateToConstructorParameter.kt b/compiler/testData/codegen/box/delegatedProperty/delegateToConstructorParameter.kt new file mode 100644 index 00000000000..c6b406cf646 --- /dev/null +++ b/compiler/testData/codegen/box/delegatedProperty/delegateToConstructorParameter.kt @@ -0,0 +1,8 @@ +// WITH_RUNTIME +class C(val x: String) + +class D(c: C) { + val x by c::x +} + +fun box(): String = D(C("OK")).x diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index c2199ce9dfc..947206c6b51 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -13256,6 +13256,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/delegatedProperty/delegateToAnotherWithSideEffects.kt"); } + @Test + @TestMetadata("delegateToConstructorParameter.kt") + public void testDelegateToConstructorParameter() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/delegateToConstructorParameter.kt"); + } + @Test @TestMetadata("delegateToGenericJavaProperty.kt") public void testDelegateToGenericJavaProperty() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 847bda4425e..c2e6c194786 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -13316,6 +13316,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/delegatedProperty/delegateToAnotherWithSideEffects.kt"); } + @Test + @TestMetadata("delegateToConstructorParameter.kt") + public void testDelegateToConstructorParameter() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/delegateToConstructorParameter.kt"); + } + @Test @TestMetadata("delegateToGenericJavaProperty.kt") public void testDelegateToGenericJavaProperty() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index f00c073f568..91ae5faca01 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -10775,6 +10775,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/delegatedProperty/delegateToAnotherWithSideEffects.kt"); } + @TestMetadata("delegateToConstructorParameter.kt") + public void testDelegateToConstructorParameter() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/delegateToConstructorParameter.kt"); + } + @TestMetadata("delegateToGenericJavaProperty.kt") public void testDelegateToGenericJavaProperty() throws Exception { runTest("compiler/testData/codegen/box/delegatedProperty/delegateToGenericJavaProperty.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index cc5166ad73f..0733926f180 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -9584,6 +9584,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/delegatedProperty/delegateToAnotherWithSideEffects.kt"); } + @TestMetadata("delegateToConstructorParameter.kt") + public void testDelegateToConstructorParameter() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/delegateToConstructorParameter.kt"); + } + @TestMetadata("delegateToOpenProperty.kt") public void testDelegateToOpenProperty() throws Exception { runTest("compiler/testData/codegen/box/delegatedProperty/delegateToOpenProperty.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 23a645e06bf..76c1bd6e39e 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -8990,6 +8990,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/delegatedProperty/delegateToAnotherWithSideEffects.kt"); } + @TestMetadata("delegateToConstructorParameter.kt") + public void testDelegateToConstructorParameter() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/delegateToConstructorParameter.kt"); + } + @TestMetadata("delegateToOpenProperty.kt") public void testDelegateToOpenProperty() throws Exception { runTest("compiler/testData/codegen/box/delegatedProperty/delegateToOpenProperty.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 16c5cedad9c..5aebd79dc1b 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -8990,6 +8990,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/delegatedProperty/delegateToAnotherWithSideEffects.kt"); } + @TestMetadata("delegateToConstructorParameter.kt") + public void testDelegateToConstructorParameter() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/delegateToConstructorParameter.kt"); + } + @TestMetadata("delegateToOpenProperty.kt") public void testDelegateToOpenProperty() throws Exception { runTest("compiler/testData/codegen/box/delegatedProperty/delegateToOpenProperty.kt");