diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 97a86258ddd..084e2e43893 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -5156,6 +5156,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt"); } + @TestMetadata("listAppend.kt") + public void testListAppend() throws Exception { + runTest("compiler/testData/codegen/box/contracts/listAppend.kt"); + } + @TestMetadata("valInWhen.kt") public void testValInWhen() throws Exception { runTest("compiler/testData/codegen/box/contracts/valInWhen.kt"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CapturingInClosureChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CapturingInClosureChecker.kt index bdd59242ab6..b5d59f36144 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CapturingInClosureChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CapturingInClosureChecker.kt @@ -14,8 +14,8 @@ import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl import org.jetbrains.kotlin.diagnostics.Errors.CAPTURED_VAL_INITIALIZATION +import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext.CAPTURED_IN_CLOSURE import org.jetbrains.kotlin.resolve.BindingTrace @@ -58,7 +58,7 @@ class CapturingInClosureChecker : CallChecker { nameElement: PsiElement ) { if (variable !is PropertyDescriptor || scopeContainer !is AnonymousFunctionDescriptor || variable.isVar) return - if ((nameElement as KtExpression).getAssignmentByLHS() == null) return + if (!isLhsOfAssignment(nameElement as KtExpression)) return val scopeDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(scopeContainer) as? KtFunction ?: return if (scopeContainer.containingDeclaration !is ConstructorDescriptor) return if (!isExactlyOnceContract(trace.bindingContext, scopeDeclaration)) return @@ -70,6 +70,11 @@ class CapturingInClosureChecker : CallChecker { } } + private fun isLhsOfAssignment(nameElement: KtExpression): Boolean { + val parent = nameElement.parent as? KtBinaryExpression ?: return false + return parent.operationToken == KtTokens.EQ && parent.left == nameElement + } + private fun isCapturedVariable(variableParent: DeclarationDescriptor, scopeContainer: DeclarationDescriptor): Boolean { if (variableParent !is FunctionDescriptor || scopeContainer == variableParent) return false diff --git a/compiler/testData/codegen/box/contracts/listAppend.kt b/compiler/testData/codegen/box/contracts/listAppend.kt new file mode 100644 index 00000000000..9af93e2c652 --- /dev/null +++ b/compiler/testData/codegen/box/contracts/listAppend.kt @@ -0,0 +1,28 @@ +// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts +// IGNORE_BACKEND: NATIVE +// WITH_RUNTIME +// KJS_WITH_FULL_RUNTIME + +import kotlin.contracts.* + +class A { + val value = arrayListOf("O") + + init { + foo { + value += "K" + } + } +} + +fun foo(block: () -> Unit) { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + block() +} + +fun box(): String { + val a = A() + return if (a.value == listOf("O", "K")) "OK" else "FAIL" +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/fieldInitialization.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/fieldInitialization.kt index 75cf936f0a9..bbfb38b0017 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/fieldInitialization.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/fieldInitialization.kt @@ -71,13 +71,13 @@ class Test1 { a += "allowed" } crossinlineMe { - b += "not allowed" + b += "not allowed" } noinlineMe { - c += "not allowed" + c += "not allowed" } notinline { - d += "not allowed" + d += "not allowed" } } } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 70da201bd0e..b3848663d69 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -5191,6 +5191,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt"); } + @TestMetadata("listAppend.kt") + public void testListAppend() throws Exception { + runTest("compiler/testData/codegen/box/contracts/listAppend.kt"); + } + @TestMetadata("valInWhen.kt") public void testValInWhen() throws Exception { runTest("compiler/testData/codegen/box/contracts/valInWhen.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 1998b9b3c7f..426661c4b00 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -5191,6 +5191,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt"); } + @TestMetadata("listAppend.kt") + public void testListAppend() throws Exception { + runTest("compiler/testData/codegen/box/contracts/listAppend.kt"); + } + @TestMetadata("valInWhen.kt") public void testValInWhen() throws Exception { runTest("compiler/testData/codegen/box/contracts/valInWhen.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 84b4b66fc87..27aad63307e 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -5156,6 +5156,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt"); } + @TestMetadata("listAppend.kt") + public void testListAppend() throws Exception { + runTest("compiler/testData/codegen/box/contracts/listAppend.kt"); + } + @TestMetadata("valInWhen.kt") public void testValInWhen() throws Exception { runTest("compiler/testData/codegen/box/contracts/valInWhen.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 7384fad2bdc..971f1aa4ad0 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -4191,6 +4191,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt"); } + @TestMetadata("listAppend.kt") + public void testListAppend() throws Exception { + runTest("compiler/testData/codegen/box/contracts/listAppend.kt"); + } + @TestMetadata("valInWhen.kt") public void testValInWhen() throws Exception { runTest("compiler/testData/codegen/box/contracts/valInWhen.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index d53a4ed8511..dcc588d8262 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -4191,6 +4191,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt"); } + @TestMetadata("listAppend.kt") + public void testListAppend() throws Exception { + runTest("compiler/testData/codegen/box/contracts/listAppend.kt"); + } + @TestMetadata("valInWhen.kt") public void testValInWhen() throws Exception { runTest("compiler/testData/codegen/box/contracts/valInWhen.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 961ae2ad22d..a07444c6f33 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -4191,6 +4191,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt"); } + @TestMetadata("listAppend.kt") + public void testListAppend() throws Exception { + runTest("compiler/testData/codegen/box/contracts/listAppend.kt"); + } + @TestMetadata("valInWhen.kt") public void testValInWhen() throws Exception { runTest("compiler/testData/codegen/box/contracts/valInWhen.kt");