diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt index 8bfbe7c3412..fc46a340766 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt @@ -82,13 +82,27 @@ private val exportForCppRuntimeAnnotation = FqName("konan.internal.ExportForCppR private val exportForCompilerAnnotation = FqName("konan.internal.ExportForCompiler") -private fun typeToHashString(type: KotlinType): String { - if (TypeUtils.isTypeParameter(type)) return "GENERIC" +private fun acyclicTypeMangler(visited: MutableSet, type: KotlinType): String { + val descriptor = TypeUtils.getTypeParameterDescriptorOrNull(type) + if (descriptor != null) { + val upperBounds = if (visited.contains(descriptor)) "" else { + + visited.add(descriptor) + + descriptor.upperBounds.map { + val bound = acyclicTypeMangler(visited, it) + if (bound == "kotlin.Any?") "" else "_$bound" + }.joinToString("") + } + return "GENERIC" + upperBounds + } var hashString = TypeUtils.getClassDescriptor(type)!!.fqNameSafe.asString() if (!type.arguments.isEmpty()) { hashString += "<${type.arguments.map { - typeToHashString(it.type) + val variance = it.projectionKind.label + val projection = if (variance == "") "" else "${variance}_" + projection + acyclicTypeMangler(visited, it.type) }.joinToString(",")}>" } @@ -96,9 +110,12 @@ private fun typeToHashString(type: KotlinType): String { return hashString } +private fun typeToHashString(type: KotlinType) + = acyclicTypeMangler(mutableSetOf(), type) + private val FunctionDescriptor.signature: String get() { - val extensionReceiverPart = this.extensionReceiverParameter?.let { "${it.type}." } ?: "" + val extensionReceiverPart = this.extensionReceiverParameter?.let { "@${typeToHashString(it.type)}." } ?: "" val argsPart = this.valueParameters.map { typeToHashString(it.type) @@ -180,4 +197,4 @@ internal val ClassDescriptor.objectInstanceFieldSymbolName: String assert (!this.isUnit()) return "kobjref:$fqNameSafe" - } \ No newline at end of file + }