Support val initialization in non-inline function with EXACTLY_ONCE effect

by generating a box for the value.
 #KT-26126 Fixed
This commit is contained in:
Ilmir Usmanov
2018-12-26 21:31:46 +03:00
parent a52f430d8f
commit 8a01da6ec6
20 changed files with 278 additions and 73 deletions
@@ -97,8 +97,7 @@ import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.*;
import static org.jetbrains.kotlin.resolve.BindingContext.*;
import static org.jetbrains.kotlin.resolve.BindingContextUtils.getDelegationConstructorCall;
import static org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure;
import static org.jetbrains.kotlin.resolve.BindingContextUtils.*;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionExpression;
@@ -3030,7 +3029,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
public int indexOfLocalNotDelegated(KtReferenceExpression lhs) {
DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, lhs);
if (isVarCapturedInClosure(bindingContext, declarationDescriptor)) {
if (isBoxedLocalCapturedInClosure(bindingContext, declarationDescriptor)) {
return -1;
}
if (declarationDescriptor instanceof LocalVariableDescriptor && ((LocalVariableDescriptor) declarationDescriptor).isDelegated()) {
@@ -4192,6 +4191,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
private void initializeLocalVariableWithFakeDefaultValue(@NotNull KtProperty variableDeclaration) {
LocalVariableDescriptor variableDescriptor = (LocalVariableDescriptor) getVariableDescriptorNotNull(variableDeclaration);
// For this kind of variables we generate boxes, i.e. we regard them as
if (isCapturedInClosureWithExactlyOnceEffect(bindingContext, variableDescriptor)) return;
assert !variableDeclaration.isVar() && !variableDeclaration.hasDelegateExpressionOrInitializer() &&
!variableDescriptor.isLateInit() : variableDeclaration.getText() + " in not variable declaration without initializer";
@@ -73,7 +73,7 @@ import static org.jetbrains.kotlin.codegen.AsmUtil.isStaticMethod;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
import static org.jetbrains.kotlin.resolve.BindingContextUtils.getDelegationConstructorCall;
import static org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure;
import static org.jetbrains.kotlin.resolve.BindingContextUtils.isBoxedLocalCapturedInClosure;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.DEFAULT_CONSTRUCTOR_MARKER;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
@@ -1869,7 +1869,7 @@ public class KotlinTypeMapper {
return null;
}
if (descriptor instanceof VariableDescriptor && isVarCapturedInClosure(bindingContext, descriptor)) {
if (descriptor instanceof VariableDescriptor && isBoxedLocalCapturedInClosure(bindingContext, descriptor)) {
return StackValue.sharedTypeForType(mapType(((VariableDescriptor) descriptor).getType()));
}