Skip to content

Commit d37a68d

Browse files
udalovSpace Team
authored andcommitted
FIR, reflection: fix contextual inline class property name clash
The code that tried to find the underlying property of an inline class by name did not take into account that properties declared in the body of the inline class can have context parameters. #KT-81584 Fixed
1 parent df399f8 commit d37a68d

File tree

27 files changed

+151
-6
lines changed

27 files changed

+151
-6
lines changed

analysis/low-level-api-fir/tests-gen/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLBlackBoxTestGenerated.java

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

analysis/low-level-api-fir/tests-gen/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLReversedBlackBoxTestGenerated.java

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,8 @@ class FirElementSerializer private constructor(
297297
builder.inlineClassUnderlyingPropertyName = getSimpleNameIndex(representation.underlyingPropertyName)
298298

299299
val property = callableMembers.single {
300-
it is FirProperty && it.receiverParameter == null && it.name == representation.underlyingPropertyName
300+
it is FirProperty && it.receiverParameter == null && it.contextParameters.isEmpty() &&
301+
it.name == representation.underlyingPropertyName
301302
}
302303

303304
if (!property.visibility.isPublicAPI) {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// TARGET_BACKEND: JVM
2+
// WITH_REFLECT
3+
// OPT_IN: kotlin.ExperimentalContextParameters
4+
// LANGUAGE: +ContextParameters
5+
6+
import kotlin.reflect.KParameter
7+
8+
@JvmInline
9+
value class Z(val value: String) {
10+
context(x: Int)
11+
val value: Int get() = x
12+
}
13+
14+
fun box(): String {
15+
val withContext = Z::class.members.single { p ->
16+
p.name == "value" && p.parameters.filter { it.kind == KParameter.Kind.CONTEXT }.isNotEmpty()
17+
}
18+
if (withContext.call(Z(""), 42) != 42) return "Fail"
19+
20+
val primary = Z::class.members.single { p ->
21+
p.name == "value" && p.parameters.filter { it.kind == KParameter.Kind.CONTEXT }.isEmpty()
22+
}
23+
return primary.call(Z("OK")) as String
24+
}

compiler/testData/diagnostics/tests/multiplatform/valueClassWithExtraProperty.fir.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN_PIPELINE_TILL: FRONTEND
1+
// RUN_PIPELINE_TILL: BACKEND
22
// IGNORE_FIR_DIAGNOSTICS
33
// LANGUAGE: +ContextParameters
44
// WITH_STDLIB

compiler/testData/diagnostics/tests/multiplatform/valueClassWithExtraProperty.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN_PIPELINE_TILL: FRONTEND
1+
// RUN_PIPELINE_TILL: BACKEND
22
// IGNORE_FIR_DIAGNOSTICS
33
// LANGUAGE: +ContextParameters
44
// WITH_STDLIB

core/descriptors/src/org/jetbrains/kotlin/resolve/inlineClassesUtils.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,5 @@ fun KotlinType.isNullableUnderlyingType(): Boolean {
7575
}
7676

7777
fun VariableDescriptor.isUnderlyingPropertyOfInlineClass(): Boolean =
78-
extensionReceiverParameter == null &&
78+
extensionReceiverParameter == null && contextReceiverParameters.isEmpty() &&
7979
(containingDeclaration as? ClassDescriptor)?.inlineClassRepresentation?.underlyingPropertyName == this.name

core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ class DeserializedClassDescriptor(
220220

221221
private fun getValueClassPropertyType(propertyName: Name): SimpleType? =
222222
memberScope.getContributedVariables(propertyName, NoLookupLocation.FROM_DESERIALIZATION)
223-
.singleOrNull { it.extensionReceiverParameter == null }?.type as SimpleType?
223+
.singleOrNull { it.extensionReceiverParameter == null && it.contextReceiverParameters.isEmpty() }?.type as SimpleType?
224224

225225
override fun toString() =
226226
"deserialized ${if (isExpect) "expect " else ""}class $name" // not using descriptor renderer to preserve laziness

core/reflection.jvm/src/kotlin/reflect/jvm/internal/calls/ValueClassAwareCaller.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,5 +393,5 @@ private fun CallableDescriptor.isGetterOfUnderlyingPropertyOfValueClass() =
393393
this is PropertyGetterDescriptor && correspondingProperty.isUnderlyingPropertyOfValueClass()
394394

395395
private fun VariableDescriptor.isUnderlyingPropertyOfValueClass(): Boolean =
396-
extensionReceiverParameter == null &&
396+
extensionReceiverParameter == null && contextReceiverParameters.isEmpty() &&
397397
(containingDeclaration as? ClassDescriptor)?.valueClassRepresentation?.containsPropertyWithName(this.name) == true

js/js.tests/klib-compatibility/tests-gen/org/jetbrains/kotlin/js/test/klib/CustomJsCompilerFirstPhaseTestGenerated.java

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)