Support 'call' for primary value of an inline class

Getter of a primary value of an inline class belongs to the box class.
Its arguments should not be unboxed when the method is called.
However, its result might require boxing if it's an inline class value.

When we have an internal primary value, there's no getter method.
In fact, we can use box/unbox methods for inline class directly
(don't forget to box the result, it may be an inline class type value).

 #KT-26748
This commit is contained in:
Dmitry Petrov
2018-11-08 16:27:32 +03:00
parent 78ee48e1cd
commit 99d8f2eb0c
15 changed files with 369 additions and 36 deletions
@@ -256,7 +256,7 @@ class PropertyReferenceCodegen(
}
val declaration = DescriptorUtils.unwrapFakeOverride(accessor).original
val method =
if (callable.containingDeclaration.isInlineClass())
if (callable.containingDeclaration.isInlineClass() && !declaration.isGetterOfUnderlyingPropertyOfInlineClass())
state.typeMapper.mapSignatureForInlineErasedClassSkipGeneric(declaration).asmMethod
else
state.typeMapper.mapAsmMethod(declaration)
@@ -17,9 +17,11 @@
package org.jetbrains.kotlin.codegen.context
import org.jetbrains.kotlin.codegen.OwnerKind
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.resolve.isGetterOfUnderlyingPropertyOfInlineClass
import org.jetbrains.kotlin.resolve.isInlineClass
import org.jetbrains.org.objectweb.asm.Type
@@ -34,13 +36,19 @@ object CodegenContextUtil {
@JvmStatic
fun isImplementationOwner(owner: CodegenContext<*>, descriptor: DeclarationDescriptor): Boolean {
if (descriptor.containingDeclaration?.isInlineClass() == true) {
if (descriptor is CallableDescriptor && descriptor.containingDeclaration.isInlineClass()) {
val isInErasedMethod = owner.contextKind == OwnerKind.ERASED_INLINE_CLASS
if (descriptor.isGetterOfUnderlyingPropertyOfInlineClass()) {
return !isInErasedMethod
}
when (descriptor) {
is FunctionDescriptor -> return isInErasedMethod
is PropertyDescriptor -> return !isInErasedMethod
}
}
return owner !is MultifileClassFacadeContext
}
}