diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/IrUnimplementedOverridesStrategy.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/IrUnimplementedOverridesStrategy.kt index 5ce37810107..9934488d660 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/IrUnimplementedOverridesStrategy.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/IrUnimplementedOverridesStrategy.kt @@ -14,9 +14,15 @@ import org.jetbrains.kotlin.ir.linkage.partial.IrUnimplementedOverridesStrategy import org.jetbrains.kotlin.ir.linkage.partial.PartiallyLinkedDeclarationOrigin import org.jetbrains.kotlin.ir.types.isNothing -internal object ImplementAsErrorThrowingStubs : IrUnimplementedOverridesStrategy { +internal class ImplementAsErrorThrowingStubs( + private val partialLinkageSupport: PartialLinkageSupportForLinker +) : IrUnimplementedOverridesStrategy { override fun computeCustomization(overridableMember: T, parent: IrClass) = - if (overridableMember.isAbstract && parent.isConcrete && !parent.delegatesToNothing) { + if (overridableMember.isAbstract + && parent.isConcrete + && !parent.delegatesToNothing + && !partialLinkageSupport.shouldBeSkipped(parent) + ) { IrUnimplementedOverridesStrategy.Customization( origin = PartiallyLinkedDeclarationOrigin.UNIMPLEMENTED_ABSTRACT_CALLABLE_MEMBER, modality = parent.modality // Use modality of class for implemented callable member. diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLinker.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLinker.kt index 2bc7a507994..0e8bec99c1f 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLinker.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLinker.kt @@ -14,6 +14,17 @@ import org.jetbrains.kotlin.ir.util.SymbolTable interface PartialLinkageSupportForLinker { val isEnabled: Boolean + /** + * Fast check to determine if the given [declaration] should be skipped from the partial linkage point of view. + * + * This check is typically used to avoid processing and patching declarations that came from stdlib or were generated + * on the fly by the compiler itself and this way are automatically supposed to be correct. + * + * Note: There is no need to call [shouldBeSkipped] prior to [exploreClassifiersInInlineLazyIrFunction] and + * [generateStubsAndPatchUsages] functions. These function do the same check internally in more optimal way. + */ + fun shouldBeSkipped(declaration: IrDeclaration): Boolean + /** * For general use in IR linker. * @@ -40,6 +51,7 @@ interface PartialLinkageSupportForLinker { companion object { val DISABLED = object : PartialLinkageSupportForLinker { override val isEnabled get() = false + override fun shouldBeSkipped(declaration: IrDeclaration) = true override fun exploreClassifiers(fakeOverrideBuilder: FakeOverrideBuilder) = Unit override fun exploreClassifiersInInlineLazyIrFunction(function: IrFunction) = Unit override fun generateStubsAndPatchUsages(symbolTable: SymbolTable, roots: () -> Sequence) = Unit diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLinkerImpl.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLinkerImpl.kt index 7077fa5babb..3baa6c55089 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLinkerImpl.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLinkerImpl.kt @@ -38,6 +38,8 @@ internal class PartialLinkageSupportForLinkerImpl( override val isEnabled get() = true + override fun shouldBeSkipped(declaration: IrDeclaration) = patcher.shouldBeSkipped(declaration) + override fun exploreClassifiers(fakeOverrideBuilder: FakeOverrideBuilder) { val entries = fakeOverrideBuilder.fakeOverrideCandidates if (entries.isEmpty()) return diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartiallyLinkedIrTreePatcher.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartiallyLinkedIrTreePatcher.kt index e1075459189..7f88a0e2ce1 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartiallyLinkedIrTreePatcher.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartiallyLinkedIrTreePatcher.kt @@ -58,6 +58,8 @@ internal class PartiallyLinkedIrTreePatcher( // Used only to generate IR expressions that throw linkage errors. private val supportForLowerings by lazy { PartialLinkageSupportForLoweringsImpl(builtIns, logLevel, messageLogger) } + fun shouldBeSkipped(declaration: IrDeclaration): Boolean = PLModule.determineModuleFor(declaration).shouldBeSkipped + fun patchModuleFragments(roots: Sequence) { roots.forEach { root -> // Optimization: Don't patch stdlib and already visited fragments. diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrides.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrides.kt index c0ec179596c..6888762424c 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrides.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrides.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.backend.common.overrides import org.jetbrains.kotlin.backend.common.linkage.partial.ImplementAsErrorThrowingStubs +import org.jetbrains.kotlin.backend.common.linkage.partial.PartialLinkageSupportForLinker import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable import org.jetbrains.kotlin.backend.common.serialization.GlobalDeclarationTable @@ -76,14 +77,17 @@ class FakeOverrideBuilder( mangler: KotlinMangler.IrMangler, typeSystem: IrTypeSystemContext, friendModules: Map>, - private val partialLinkageEnabled: Boolean, + private val partialLinkageSupport: PartialLinkageSupportForLinker, val platformSpecificClassFilter: FakeOverrideClassFilter = DefaultFakeOverrideClassFilter, private val fakeOverrideDeclarationTable: DeclarationTable = FakeOverrideDeclarationTable(mangler) { builder, table -> IdSignatureSerializer(builder, table) } ) : FakeOverrideBuilderStrategy( friendModules = friendModules, - unimplementedOverridesStrategy = if (partialLinkageEnabled) ImplementAsErrorThrowingStubs else ProcessAsFakeOverrides + unimplementedOverridesStrategy = if (partialLinkageSupport.isEnabled) + ImplementAsErrorThrowingStubs(partialLinkageSupport) + else + ProcessAsFakeOverrides ) { private val haveFakeOverrides = mutableSetOf() @@ -186,7 +190,7 @@ class FakeOverrideBuilder( val symbol = linker.tryReferencingSimpleFunctionByLocalSignature(parent, signature) ?: symbolTable.referenceSimpleFunction(signature) - if (!partialLinkageEnabled + if (!partialLinkageSupport.isEnabled || !symbol.isBound || symbol.owner.let { boundFunction -> boundFunction.isSuspend == function.isSuspend && !boundFunction.isInline && !function.isInline @@ -221,7 +225,7 @@ class FakeOverrideBuilder( val symbol = linker.tryReferencingPropertyByLocalSignature(parent, signature) ?: symbolTable.referenceProperty(signature) - if (!partialLinkageEnabled + if (!partialLinkageSupport.isEnabled || !symbol.isBound || symbol.owner.let { boundProperty -> boundProperty.getter?.isInline != true && boundProperty.setter?.isInline != true diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt index 3b0a701f4bf..038bdaddd02 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt @@ -45,7 +45,7 @@ class JsIrLinker( mangler = JsManglerIr, typeSystem = IrTypeSystemContextImpl(builtIns), friendModules = friendModules, - partialLinkageEnabled = partialLinkageSupport.isEnabled + partialLinkageSupport = partialLinkageSupport ) override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean = diff --git a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/backend/jvm/serialization/deserializeLazyDeclarations.kt b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/backend/jvm/serialization/deserializeLazyDeclarations.kt index 15bc3c2f07d..445b960c237 100644 --- a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/backend/jvm/serialization/deserializeLazyDeclarations.kt +++ b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/backend/jvm/serialization/deserializeLazyDeclarations.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.backend.jvm.serialization +import org.jetbrains.kotlin.backend.common.linkage.partial.PartialLinkageSupportForLinker import org.jetbrains.kotlin.backend.common.overrides.DefaultFakeOverrideClassFilter import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideDeclarationTable @@ -162,7 +163,7 @@ fun makeSimpleFakeOverrideBuilder( typeSystemContext, fakeOverrideDeclarationTable = PrePopulatedDeclarationTable(symbolDeserializer.deserializedSymbols), friendModules = emptyMap(), // TODO: provide friend modules - partialLinkageEnabled = false + partialLinkageSupport = PartialLinkageSupportForLinker.DISABLED ) } diff --git a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt index 01223fecaf4..56a12cf6be6 100644 --- a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt +++ b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt @@ -50,7 +50,7 @@ class JvmIrLinker( mangler = JvmIrMangler, typeSystem = typeSystem, friendModules = emptyMap(), // TODO: provide friend modules - partialLinkageEnabled = false + partialLinkageSupport = PartialLinkageSupportForLinker.DISABLED ) private val javaName = Name.identifier("java") diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt index d2f8f42ac41..69fcbe913bb 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt @@ -376,7 +376,7 @@ internal class KonanIrLinker( mangler = KonanManglerIr, typeSystem = IrTypeSystemContextImpl(builtIns), friendModules = friendModules, - partialLinkageEnabled = partialLinkageSupport.isEnabled, + partialLinkageSupport = partialLinkageSupport, platformSpecificClassFilter = KonanFakeOverrideClassFilter )