[PL] Fix: Don't try to implement non-implemented fake overrides in stdlib & co

This commit is contained in:
Dmitriy Dolovov
2023-04-16 22:01:18 +02:00
committed by Space Team
parent dd8eedb8da
commit 997b6e6722
9 changed files with 37 additions and 10 deletions
@@ -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 <T : IrOverridableMember> 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.
@@ -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<IrModuleFragment>) = Unit
@@ -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
@@ -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<IrModuleFragment>) {
roots.forEach { root ->
// Optimization: Don't patch stdlib and already visited fragments.
@@ -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<String, Collection<String>>,
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<IrClass>()
@@ -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
@@ -45,7 +45,7 @@ class JsIrLinker(
mangler = JsManglerIr,
typeSystem = IrTypeSystemContextImpl(builtIns),
friendModules = friendModules,
partialLinkageEnabled = partialLinkageSupport.isEnabled
partialLinkageSupport = partialLinkageSupport
)
override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean =
@@ -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
)
}
@@ -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")
@@ -376,7 +376,7 @@ internal class KonanIrLinker(
mangler = KonanManglerIr,
typeSystem = IrTypeSystemContextImpl(builtIns),
friendModules = friendModules,
partialLinkageEnabled = partialLinkageSupport.isEnabled,
partialLinkageSupport = partialLinkageSupport,
platformSpecificClassFilter = KonanFakeOverrideClassFilter
)