diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt index fcfa9adc44e..e61c3756f9c 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt @@ -243,7 +243,7 @@ abstract class KotlinIrLinker( fileProto.declarationIdList.forEach { val uniqIdKey = it.uniqIdKey(moduleDescriptor) - reversedFileIndex.put(uniqIdKey, file) + reversedFileIndex.getOrPut(uniqIdKey) { mutableListOf() }.add(file) } when (deserializationStrategy) { @@ -299,16 +299,16 @@ abstract class KotlinIrLinker( return codedInputStream } - private val reversedFileIndex = mutableMapOf() + private val reversedFileIndex = mutableMapOf>() private val UniqIdKey.moduleOfOrigin get() = - this.moduleDescriptor ?: reversedFileIndex[this]?.packageFragmentDescriptor?.containingDeclaration + this.moduleDescriptor ?: reversedFileIndex[this]?.handleClashes(this)?.packageFragmentDescriptor?.containingDeclaration private fun deserializeTopLevelDeclaration(uniqIdKey: UniqIdKey): IrDeclaration { val proto = loadTopLevelDeclarationProto(uniqIdKey) return deserializersForModules[uniqIdKey.moduleOfOrigin]!! - .deserializeDeclaration(proto, reversedFileIndex[uniqIdKey]!!) + .deserializeDeclaration(proto, reversedFileIndex[uniqIdKey]!!.handleClashes(uniqIdKey)) } protected abstract fun reader(moduleDescriptor: ModuleDescriptor, uniqId: UniqId): ByteArray @@ -316,6 +316,14 @@ abstract class KotlinIrLinker( protected abstract fun readType(moduleDescriptor: ModuleDescriptor, typeIndex: Int): ByteArray protected abstract fun readString(moduleDescriptor: ModuleDescriptor, stringIndex: Int): ByteArray + protected open fun List.handleClashes(uniqIdKey: UniqIdKey): IrFile { + if (size == 1) + return this[0] + assert(size != 0) + error("UniqId clash: ${uniqIdKey.uniqId.index}. Found in the " + + "[${this.joinToString { it.packageFragmentDescriptor.containingDeclaration.name.asString() }}]") + } + private fun loadTopLevelDeclarationProto(uniqIdKey: UniqIdKey): KotlinIr.IrDeclaration { val stream = reader(uniqIdKey.moduleOfOrigin!!, uniqIdKey.uniqId).codedInputStream return KotlinIr.IrDeclaration.parseFrom(stream, newInstance()) @@ -358,7 +366,7 @@ abstract class KotlinIrLinker( } val reachable = deserializeTopLevelDeclaration(key) - val file = reversedFileIndex[key]!! + val file = reversedFileIndex[key]!!.handleClashes(key) file.declarations.add(reachable) deserializeFileAnnotationsIfFirstUse(moduleOfOrigin, file) 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 a252cdde0a9..d21d335bc22 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 @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.LoggingContext import org.jetbrains.kotlin.backend.common.serialization.* import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.ir.backend.js.kotlinLibrary +import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol import org.jetbrains.kotlin.ir.util.SymbolTable @@ -45,6 +46,16 @@ class JsIrLinker( override fun readString(moduleDescriptor: ModuleDescriptor, stringIndex: Int) = moduleDescriptor.kotlinLibrary.string(stringIndex) + override fun List.handleClashes(uniqIdKey: UniqIdKey): IrFile { + if (size == 1) + return this[0] + assert(size != 0) + error("UniqId clash: ${uniqIdKey.uniqId.index}. Found in the " + + "[${this.joinToString { it.packageFragmentDescriptor.containingDeclaration.userName }}]") + } + + private val ModuleDescriptor.userName get() = kotlinLibrary.libraryFile.absolutePath + override fun declareForwardDeclarations() { // since for `knownBuiltIns` such as FunctionN it is possible to have unbound symbols after deserialization // reference them through out lazy symbol table