diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 9db30476638..082a82c6ff4 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -1707,11 +1707,7 @@ public class ExpressionCodegen extends KtVisitor impleme if (descriptor instanceof PropertyDescriptor) { PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; - boolean isUnderlyingPropertyOfInlineClass = - InlineClassesUtilsKt.isInlineClass(propertyDescriptor.getContainingDeclaration()) && - JvmCodegenUtil.hasBackingField(propertyDescriptor, contextKind(), bindingContext); - - if (isUnderlyingPropertyOfInlineClass) { + if (InlineClassesUtilsKt.isUnderlyingPropertyOfInlineClass(propertyDescriptor)) { KotlinType propertyType = propertyDescriptor.getType(); return StackValue.underlyingValueOfInlineClass(typeMapper.mapType(propertyType), propertyType, receiver); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index 5b6d2e61df7..57db28dd992 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -23,7 +23,6 @@ import org.jetbrains.kotlin.codegen.coroutines.SuspendFunctionGenerationStrategy import org.jetbrains.kotlin.codegen.coroutines.SuspendInlineFunctionGenerationStrategy; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; -import org.jetbrains.kotlin.codegen.state.TypeMapperUtilsKt; import org.jetbrains.kotlin.config.JvmDefaultMode; import org.jetbrains.kotlin.config.JvmTarget; import org.jetbrains.kotlin.config.LanguageFeature; @@ -295,8 +294,7 @@ public class FunctionCodegen { // descriptor corresponds to the underlying value if (functionDescriptor instanceof PropertyAccessorDescriptor) { PropertyDescriptor property = ((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty(); - // property for the underlying value - if (JvmCodegenUtil.hasBackingField(property, contextKind, bindingContext)) { + if (InlineClassesUtilsKt.isUnderlyingPropertyOfInlineClass(property)) { return false; } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt index 82004b657c7..47b999be5af 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt @@ -135,7 +135,7 @@ object ExpectedActualDeclarationChecker : DeclarationChecker { if (compatibility.allStrongIncompatibilities()) return if (Compatible in compatibility) { - if (checkActual && requireActualModifier(descriptor, trace)) { + if (checkActual && requireActualModifier(descriptor)) { trace.report(Errors.ACTUAL_MISSING.on(reportOn)) } @@ -204,16 +204,14 @@ object ExpectedActualDeclarationChecker : DeclarationChecker { // - annotation constructors, because annotation classes can only have one constructor // - inline class primary constructors, because inline class must have primary constructor // - value parameter inside primary constructor of inline class, because inline class must have one value parameter - private fun requireActualModifier(descriptor: MemberDescriptor, trace: BindingTrace): Boolean { + private fun requireActualModifier(descriptor: MemberDescriptor): Boolean { return !descriptor.isAnnotationConstructor() && !descriptor.isPrimaryConstructorOfInlineClass() && - !isMainPropertyOfInlineClass(descriptor, trace) + !isUnderlyingPropertyOfInlineClass(descriptor) } - private fun isMainPropertyOfInlineClass(descriptor: MemberDescriptor, trace: BindingTrace): Boolean { - if (descriptor !is PropertyDescriptor) return false - if (!descriptor.containingDeclaration.isInlineClass()) return false - return trace.bindingContext[BindingContext.BACKING_FIELD_REQUIRED, descriptor] == true + private fun isUnderlyingPropertyOfInlineClass(descriptor: MemberDescriptor): Boolean { + return descriptor is PropertyDescriptor && descriptor.isUnderlyingPropertyOfInlineClass() } // This should ideally be handled by CallableMemberDescriptor.Kind, but default constructors have kind DECLARATION and non-empty source. diff --git a/compiler/testData/compileKotlinAgainstKotlin/callDeserializedPropertyOnInlineClassType.kt b/compiler/testData/compileKotlinAgainstKotlin/callDeserializedPropertyOnInlineClassType.kt new file mode 100644 index 00000000000..b3978712ea0 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstKotlin/callDeserializedPropertyOnInlineClassType.kt @@ -0,0 +1,18 @@ +// FILE: A.kt + +package a + +@Suppress("UNSUPPORTED_FEATURE") +inline class Foo(val x: IntArray) { + val size: Int get() = x.size +} + +// FILE: B.kt + +import a.* + +fun box(): String { + val a = Foo(intArrayOf(3, 4)) + if (a.size != 2) return "Fail" + return "OK" +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java index 365b1675691..f8d92f6e4ff 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java @@ -39,6 +39,11 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl runTest("compiler/testData/compileKotlinAgainstKotlin/annotationsOnTypeAliases.kt"); } + @TestMetadata("callDeserializedPropertyOnInlineClassType.kt") + public void testCallDeserializedPropertyOnInlineClassType() throws Exception { + runTest("compiler/testData/compileKotlinAgainstKotlin/callDeserializedPropertyOnInlineClassType.kt"); + } + @TestMetadata("callsToMultifileClassFromOtherPackage.kt") public void testCallsToMultifileClassFromOtherPackage() throws Exception { runTest("compiler/testData/compileKotlinAgainstKotlin/callsToMultifileClassFromOtherPackage.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/inlineClassesUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/inlineClassesUtils.kt index 2768bb95590..ff930abb2db 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/inlineClassesUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/inlineClassesUtils.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.resolve import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.types.KotlinType @@ -39,3 +40,10 @@ fun KotlinType.isNullableUnderlyingType(): Boolean { return TypeUtils.isNullableType(underlyingType) } + +fun PropertyDescriptor.isUnderlyingPropertyOfInlineClass(): Boolean { + val containingDeclaration = this.containingDeclaration + if (!containingDeclaration.isInlineClass()) return false + + return (containingDeclaration as ClassDescriptor).underlyingRepresentation()?.name == this.name +} \ No newline at end of file