From ca32722b0a043e27e986930c6d8b0c90024f09b8 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Tue, 14 Nov 2023 13:27:50 +0200 Subject: [PATCH] [FIR2IR] Consider expectness of containing class in FakeOverrideIdentifier ```kotlin // MODULE: a interface Base { fun foo() } expect interface Derived : Base { // f/o fun foo() // (1) } // MODULE: b()()(a) actual interface Derived : Base { // f/o fun foo() // (2) } ``` Before this change `FakeOverrideIdentifier` for (1) and (2) were the same, which led to the problem when referencing (2) in `b` module returned symbol (1) This behavior affected two places: 1. Referencing function symbol in some call. Here it wasn't an issue, because IrActualizer changed reference to (2) anyway 2. Creation of IR declaration for (2) in `FakeOverrideGenerator.createFakeOverriddenIfNeeded`. Previously it worked because of the following hack at `FakeOverrideGenerator:283-286` ``` takeIf { it.ownerIfBound()?.parent == irClass } ``` Generator referenced symbol (1), checked the parent and refused it, because its parent was different from `actual interface Derived`. Then it called declaration storage to create new IR declaration for (2), which unconditionally created new symbol for (2). But after previous commit logic of creation new declarations was changed: declaration storage extract potentially unbound symbol from cache and then creates a new declaration with this symbol. But cache still contains symbol (1) for given FakeOverrideIdentifier, which leads to the problem that we try to create new IR declaration for already bound symbol To fix it and be able to distinguish f/o ids for (1) and (2) additional flag is added to FakeOverrideIdentifier, which shows if containing class of corresponding f/o is expect or not --- .../fir/backend/Fir2IrDeclarationStorage.kt | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) 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 2af3af269e3..4f83e793830 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 @@ -122,7 +122,25 @@ class Fir2IrDeclarationStorage( private val irForFirSessionDependantDeclarationMap: MutableMap = commonMemberStorage.irForFirSessionDependantDeclarationMap - data class FakeOverrideIdentifier(val originalSymbol: FirCallableSymbol<*>, val dispatchReceiverLookupTag: ConeClassLikeLookupTag) + data class FakeOverrideIdentifier( + val originalSymbol: FirCallableSymbol<*>, + val dispatchReceiverLookupTag: ConeClassLikeLookupTag, + val parentIsExpect: Boolean, + ) { + companion object { + context(Fir2IrComponents) + operator fun invoke( + originalSymbol: FirCallableSymbol<*>, + dispatchReceiverLookupTag: ConeClassLikeLookupTag, + ): FakeOverrideIdentifier { + return FakeOverrideIdentifier( + originalSymbol, + dispatchReceiverLookupTag, + dispatchReceiverLookupTag.toFirRegularClass(session)?.isExpect == true + ) + } + } + } sealed class FirOverrideKey { data class Signature(val signature: IdSignature) : FirOverrideKey()