[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.linkage.partial.PartiallyLinkedDeclarationOrigin
import org.jetbrains.kotlin.ir.types.isNothing 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) = 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( IrUnimplementedOverridesStrategy.Customization(
origin = PartiallyLinkedDeclarationOrigin.UNIMPLEMENTED_ABSTRACT_CALLABLE_MEMBER, origin = PartiallyLinkedDeclarationOrigin.UNIMPLEMENTED_ABSTRACT_CALLABLE_MEMBER,
modality = parent.modality // Use modality of class for implemented 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 { interface PartialLinkageSupportForLinker {
val isEnabled: Boolean 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. * For general use in IR linker.
* *
@@ -40,6 +51,7 @@ interface PartialLinkageSupportForLinker {
companion object { companion object {
val DISABLED = object : PartialLinkageSupportForLinker { val DISABLED = object : PartialLinkageSupportForLinker {
override val isEnabled get() = false override val isEnabled get() = false
override fun shouldBeSkipped(declaration: IrDeclaration) = true
override fun exploreClassifiers(fakeOverrideBuilder: FakeOverrideBuilder) = Unit override fun exploreClassifiers(fakeOverrideBuilder: FakeOverrideBuilder) = Unit
override fun exploreClassifiersInInlineLazyIrFunction(function: IrFunction) = Unit override fun exploreClassifiersInInlineLazyIrFunction(function: IrFunction) = Unit
override fun generateStubsAndPatchUsages(symbolTable: SymbolTable, roots: () -> Sequence<IrModuleFragment>) = Unit override fun generateStubsAndPatchUsages(symbolTable: SymbolTable, roots: () -> Sequence<IrModuleFragment>) = Unit
@@ -38,6 +38,8 @@ internal class PartialLinkageSupportForLinkerImpl(
override val isEnabled get() = true override val isEnabled get() = true
override fun shouldBeSkipped(declaration: IrDeclaration) = patcher.shouldBeSkipped(declaration)
override fun exploreClassifiers(fakeOverrideBuilder: FakeOverrideBuilder) { override fun exploreClassifiers(fakeOverrideBuilder: FakeOverrideBuilder) {
val entries = fakeOverrideBuilder.fakeOverrideCandidates val entries = fakeOverrideBuilder.fakeOverrideCandidates
if (entries.isEmpty()) return if (entries.isEmpty()) return
@@ -58,6 +58,8 @@ internal class PartiallyLinkedIrTreePatcher(
// Used only to generate IR expressions that throw linkage errors. // Used only to generate IR expressions that throw linkage errors.
private val supportForLowerings by lazy { PartialLinkageSupportForLoweringsImpl(builtIns, logLevel, messageLogger) } private val supportForLowerings by lazy { PartialLinkageSupportForLoweringsImpl(builtIns, logLevel, messageLogger) }
fun shouldBeSkipped(declaration: IrDeclaration): Boolean = PLModule.determineModuleFor(declaration).shouldBeSkipped
fun patchModuleFragments(roots: Sequence<IrModuleFragment>) { fun patchModuleFragments(roots: Sequence<IrModuleFragment>) {
roots.forEach { root -> roots.forEach { root ->
// Optimization: Don't patch stdlib and already visited fragments. // Optimization: Don't patch stdlib and already visited fragments.
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.backend.common.overrides package org.jetbrains.kotlin.backend.common.overrides
import org.jetbrains.kotlin.backend.common.linkage.partial.ImplementAsErrorThrowingStubs 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.CompatibilityMode
import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable
import org.jetbrains.kotlin.backend.common.serialization.GlobalDeclarationTable import org.jetbrains.kotlin.backend.common.serialization.GlobalDeclarationTable
@@ -76,14 +77,17 @@ class FakeOverrideBuilder(
mangler: KotlinMangler.IrMangler, mangler: KotlinMangler.IrMangler,
typeSystem: IrTypeSystemContext, typeSystem: IrTypeSystemContext,
friendModules: Map<String, Collection<String>>, friendModules: Map<String, Collection<String>>,
private val partialLinkageEnabled: Boolean, private val partialLinkageSupport: PartialLinkageSupportForLinker,
val platformSpecificClassFilter: FakeOverrideClassFilter = DefaultFakeOverrideClassFilter, val platformSpecificClassFilter: FakeOverrideClassFilter = DefaultFakeOverrideClassFilter,
private val fakeOverrideDeclarationTable: DeclarationTable = FakeOverrideDeclarationTable(mangler) { builder, table -> private val fakeOverrideDeclarationTable: DeclarationTable = FakeOverrideDeclarationTable(mangler) { builder, table ->
IdSignatureSerializer(builder, table) IdSignatureSerializer(builder, table)
} }
) : FakeOverrideBuilderStrategy( ) : FakeOverrideBuilderStrategy(
friendModules = friendModules, friendModules = friendModules,
unimplementedOverridesStrategy = if (partialLinkageEnabled) ImplementAsErrorThrowingStubs else ProcessAsFakeOverrides unimplementedOverridesStrategy = if (partialLinkageSupport.isEnabled)
ImplementAsErrorThrowingStubs(partialLinkageSupport)
else
ProcessAsFakeOverrides
) { ) {
private val haveFakeOverrides = mutableSetOf<IrClass>() private val haveFakeOverrides = mutableSetOf<IrClass>()
@@ -186,7 +190,7 @@ class FakeOverrideBuilder(
val symbol = linker.tryReferencingSimpleFunctionByLocalSignature(parent, signature) val symbol = linker.tryReferencingSimpleFunctionByLocalSignature(parent, signature)
?: symbolTable.referenceSimpleFunction(signature) ?: symbolTable.referenceSimpleFunction(signature)
if (!partialLinkageEnabled if (!partialLinkageSupport.isEnabled
|| !symbol.isBound || !symbol.isBound
|| symbol.owner.let { boundFunction -> || symbol.owner.let { boundFunction ->
boundFunction.isSuspend == function.isSuspend && !boundFunction.isInline && !function.isInline boundFunction.isSuspend == function.isSuspend && !boundFunction.isInline && !function.isInline
@@ -221,7 +225,7 @@ class FakeOverrideBuilder(
val symbol = linker.tryReferencingPropertyByLocalSignature(parent, signature) val symbol = linker.tryReferencingPropertyByLocalSignature(parent, signature)
?: symbolTable.referenceProperty(signature) ?: symbolTable.referenceProperty(signature)
if (!partialLinkageEnabled if (!partialLinkageSupport.isEnabled
|| !symbol.isBound || !symbol.isBound
|| symbol.owner.let { boundProperty -> || symbol.owner.let { boundProperty ->
boundProperty.getter?.isInline != true && boundProperty.setter?.isInline != true boundProperty.getter?.isInline != true && boundProperty.setter?.isInline != true
@@ -45,7 +45,7 @@ class JsIrLinker(
mangler = JsManglerIr, mangler = JsManglerIr,
typeSystem = IrTypeSystemContextImpl(builtIns), typeSystem = IrTypeSystemContextImpl(builtIns),
friendModules = friendModules, friendModules = friendModules,
partialLinkageEnabled = partialLinkageSupport.isEnabled partialLinkageSupport = partialLinkageSupport
) )
override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean = override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean =
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.backend.jvm.serialization 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.DefaultFakeOverrideClassFilter
import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder
import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideDeclarationTable import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideDeclarationTable
@@ -162,7 +163,7 @@ fun makeSimpleFakeOverrideBuilder(
typeSystemContext, typeSystemContext,
fakeOverrideDeclarationTable = PrePopulatedDeclarationTable(symbolDeserializer.deserializedSymbols), fakeOverrideDeclarationTable = PrePopulatedDeclarationTable(symbolDeserializer.deserializedSymbols),
friendModules = emptyMap(), // TODO: provide friend modules friendModules = emptyMap(), // TODO: provide friend modules
partialLinkageEnabled = false partialLinkageSupport = PartialLinkageSupportForLinker.DISABLED
) )
} }
@@ -50,7 +50,7 @@ class JvmIrLinker(
mangler = JvmIrMangler, mangler = JvmIrMangler,
typeSystem = typeSystem, typeSystem = typeSystem,
friendModules = emptyMap(), // TODO: provide friend modules friendModules = emptyMap(), // TODO: provide friend modules
partialLinkageEnabled = false partialLinkageSupport = PartialLinkageSupportForLinker.DISABLED
) )
private val javaName = Name.identifier("java") private val javaName = Name.identifier("java")
@@ -376,7 +376,7 @@ internal class KonanIrLinker(
mangler = KonanManglerIr, mangler = KonanManglerIr,
typeSystem = IrTypeSystemContextImpl(builtIns), typeSystem = IrTypeSystemContextImpl(builtIns),
friendModules = friendModules, friendModules = friendModules,
partialLinkageEnabled = partialLinkageSupport.isEnabled, partialLinkageSupport = partialLinkageSupport,
platformSpecificClassFilter = KonanFakeOverrideClassFilter platformSpecificClassFilter = KonanFakeOverrideClassFilter
) )