diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index cf34c7e839d..942b46abd4b 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -1191,13 +1191,15 @@ class Fir2IrDeclarationStorage( if (fir.isLocal) { return localStorage.getDelegatedProperty(fir)?.symbol ?: getIrVariableSymbol(fir) } - val unmatchedReceiver = dispatchReceiverLookupTag != firPropertySymbol.containingClass() + val containingClassLookupTag = firPropertySymbol.containingClass() + val unmatchedReceiver = dispatchReceiverLookupTag != containingClassLookupTag if (unmatchedReceiver) { generateLazyFakeOverrides(fir.name, dispatchReceiverLookupTag) } - val originalSymbol = getIrCallableSymbol( + + fun ConeClassLikeLookupTag?.getIrCallableSymbol() = getIrCallableSymbol( firPropertySymbol, - dispatchReceiverLookupTag, + dispatchReceiverLookupTag = this, getCachedIrDeclaration = ::getCachedIrProperty, createIrDeclaration = { parent, origin -> createIrProperty(fir, parent, predefinedOrigin = origin) }, createIrLazyDeclaration = { signature, lazyParent, declarationOrigin -> @@ -1219,13 +1221,34 @@ class Fir2IrDeclarationStorage( return symbol } ) + + val originalSymbol = dispatchReceiverLookupTag.getIrCallableSymbol() + val originalProperty = originalSymbol.owner as IrProperty + + fun IrProperty.isIllegalFakeOverride(): Boolean { + if (!isFakeOverride) return false + val overriddenSymbols = overriddenSymbols + if (overriddenSymbols.isEmpty() || overriddenSymbols.any { it.owner.isIllegalFakeOverride() }) { + return true + } + return false + } + + if (dispatchReceiverLookupTag != null && + firPropertySymbol is FirSyntheticPropertySymbol && + originalProperty.isIllegalFakeOverride() + ) { + // Fallback for a synthetic property complex case + return containingClassLookupTag.getIrCallableSymbol() + } + return if (dispatchReceiverLookupTag is ConeClassLookupTagWithFixedSymbol && - dispatchReceiverLookupTag != firPropertySymbol.containingClass() + dispatchReceiverLookupTag != containingClassLookupTag ) { val dispatchReceiverIrClass = classifierStorage.getIrClassSymbol(dispatchReceiverLookupTag.toSymbol(session) as FirClassSymbol).owner dispatchReceiverIrClass.declarations.find { - it is IrProperty && it.isFakeOverride && it.name == fir.name && it.overrides(originalSymbol.owner as IrProperty) + it is IrProperty && it.isFakeOverride && it.name == fir.name && it.overrides(originalProperty) }?.symbol as IrPropertySymbol } else { originalSymbol diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 810b71f61c2..6b73e020b60 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -16342,6 +16342,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/fir/ConstValAccess.kt"); } + @Test + @TestMetadata("CustomHashSetSize.kt") + public void testCustomHashSetSize() throws Exception { + runTest("compiler/testData/codegen/box/fir/CustomHashSetSize.kt"); + } + @Test @TestMetadata("CustomThrowableMessage.kt") public void testCustomThrowableMessage() throws Exception { diff --git a/compiler/testData/codegen/box/fir/CustomHashSetSize.kt b/compiler/testData/codegen/box/fir/CustomHashSetSize.kt new file mode 100644 index 00000000000..36b81368a1b --- /dev/null +++ b/compiler/testData/codegen/box/fir/CustomHashSetSize.kt @@ -0,0 +1,65 @@ +// TARGET_BACKEND: JVM_IR +// WITH_RUNTIME + +// MODULE: m1 +// FILE: m1/THash.java + +package m1; + +public class THash { + + public int size() { return 1; } +} + +// FILE: m1/TObjectHash.java + +package m1; + +public class TObjectHash extends THash {} + +// FILE: m1/THashSet.java + +package m1; +import java.util.*; + +public class THashSet extends TObjectHash implements Set { + public Iterator iterator() { return null; } + + public boolean isEmpty() { return false; } + + public boolean contains(Object o) { return false; } + + public Object[] toArray() { return new Object[1]; } + + public T[] toArray(T[] a) { throw new RuntimeException(); } + + public boolean add(T e) { return false; } + + public boolean remove(Object o) { return false; } + + public boolean containsAll(Collection c) { return false; } + + public boolean addAll(Collection c) { return false; } + + public boolean retainAll(Collection c) { return false; } + + public boolean removeAll(Collection c) { return false; } + + public void clear() {} +} + +// MODULE: m2(m1) +// FILE: box.kt + +package m2 +import m1.THashSet + +interface HeaderSet : Set + +class MutableHeaderSet : HeaderSet, MutableSet, THashSet() + +fun box(): String { + val size1 = THashSet().size + val size2 = MutableHeaderSet().size + return if (size1 == 1 && size2 == 1) "OK" else "$size1/$size2" +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index db1879815ff..df112710317 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -16342,6 +16342,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/fir/ConstValAccess.kt"); } + @Test + @TestMetadata("CustomHashSetSize.kt") + public void testCustomHashSetSize() throws Exception { + runTest("compiler/testData/codegen/box/fir/CustomHashSetSize.kt"); + } + @Test @TestMetadata("CustomThrowableMessage.kt") public void testCustomThrowableMessage() throws Exception {