diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/BaseKotlinMangleComputer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/BaseKotlinMangleComputer.kt index 6ad7c7fc2bf..d25e0baecd0 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/BaseKotlinMangleComputer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/BaseKotlinMangleComputer.kt @@ -19,10 +19,13 @@ import org.jetbrains.kotlin.types.model.* * @param Session An additional context used for type computations. * @property builder A string builder to write the mangled name into. * @property mode The mangle mode. + * @property allowOutOfScopeTypeParameters Whether to throw an exception if the container of a referenced type parameter is not found + * in the current scope. This often happens in the lowered IR and should never happen in the IR emitted by the frontend. */ abstract class BaseKotlinMangleComputer( protected val builder: StringBuilder, - protected val mode: MangleMode + protected val mode: MangleMode, + protected val allowOutOfScopeTypeParameters: Boolean = false, ) : KotlinMangleComputer where Declaration : Any, Type : KotlinTypeMarker, @@ -120,7 +123,7 @@ abstract class BaseKotlinMangleComputer= 0) { + require(allowOutOfScopeTypeParameters || containerIndex >= 0) { "No container found for type parameter '${getTypeParameterName(typeParameter)}' of '${renderDeclaration(parent)}'" } appendSignature(containerIndex) diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/ir/IrMangleComputer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/ir/IrMangleComputer.kt index 93ab73d67e6..e586f0369d6 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/ir/IrMangleComputer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/ir/IrMangleComputer.kt @@ -22,7 +22,8 @@ import org.jetbrains.kotlin.ir.visitors.acceptVoid open class IrMangleComputer( builder: StringBuilder, mode: MangleMode, - protected val compatibleMode: Boolean + protected val compatibleMode: Boolean, + allowOutOfScopeTypeParameters: Boolean = false, ) : BaseKotlinMangleComputer< /*Declaration=*/IrDeclaration, /*Type=*/IrType, @@ -31,7 +32,7 @@ open class IrMangleComputer( /*TypeParameterContainer=*/IrDeclaration, /*FunctionDeclaration=*/IrFunction, /*Session=*/Nothing?, - >(builder, mode) { + >(builder, mode, allowOutOfScopeTypeParameters) { final override fun getTypeSystemContext(session: Nothing?) = object : IrTypeSystemContext { override val irBuiltIns: IrBuiltIns diff --git a/compiler/testData/codegen/box/closures/closureCapturingGenericParam.kt b/compiler/testData/codegen/box/closures/closureCapturingGenericParam.kt index cfd69850bd0..654c52b08aa 100644 --- a/compiler/testData/codegen/box/closures/closureCapturingGenericParam.kt +++ b/compiler/testData/codegen/box/closures/closureCapturingGenericParam.kt @@ -14,7 +14,32 @@ class N(val v: Int) : IntConvertible { override fun toInt() = v } +interface Grouping { + fun keyOf(element: GroupingInputTP): GroupingOutputTP +} + +fun groupingBy(keySelector: (Char) -> GroupingByTP): Grouping { + + fun foo(p0: T, p1: GroupingByTP) {} + + foo(0, keySelector('a')) + + class A(p0: T, p1: GroupingByTP) {} + + A(0, keySelector('a')) + + return object : Grouping { + override fun keyOf(element: Char): GroupingByTP = keySelector(element) + } +} + +class Delft { + fun getComparator(other: DelftTP) = { this == other } +} + fun box(): String { - if (computeSum(arrayOf(N(2), N(14))) != 16) return "Fail" + if (computeSum(arrayOf(N(2), N(14))) != 16) return "Fail1" + + if (groupingBy { it }.keyOf('A') != 'A') return "Fail2" return "OK" } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt index 143a74104cc..660c36731f2 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt @@ -30,7 +30,7 @@ import org.jetbrains.kotlin.name.Name // TODO: do not serialize descriptors of non-exported declarations. object KonanBinaryInterface { - private val mangler = object : AbstractKonanIrMangler(true) {} + private val mangler = object : AbstractKonanIrMangler(withReturnType = true, allowOutOfScopeTypeParameters = true) {} private val exportChecker = mangler.getExportChecker(compatibleMode = true) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanMangler.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanMangler.kt index 54194d2ab6f..968c3636f3b 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanMangler.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanMangler.kt @@ -15,10 +15,14 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.util.hasAnnotation -abstract class AbstractKonanIrMangler(private val withReturnType: Boolean) : IrBasedKotlinManglerImpl() { +abstract class AbstractKonanIrMangler( + private val withReturnType: Boolean, + private val allowOutOfScopeTypeParameters: Boolean = false +) : IrBasedKotlinManglerImpl() { override fun getExportChecker(compatibleMode: Boolean): IrExportCheckerVisitor = KonanIrExportChecker(compatibleMode) - override fun getMangleComputer(mode: MangleMode, compatibleMode: Boolean): IrMangleComputer = KonanIrManglerComputer(StringBuilder(256), mode, compatibleMode, withReturnType) + override fun getMangleComputer(mode: MangleMode, compatibleMode: Boolean): IrMangleComputer = + KonanIrManglerComputer(StringBuilder(256), mode, compatibleMode, withReturnType, allowOutOfScopeTypeParameters) override fun IrDeclaration.isPlatformSpecificExport(): Boolean { if (this is IrSimpleFunction) if (isFakeOverride) return false @@ -51,8 +55,15 @@ abstract class AbstractKonanIrMangler(private val withReturnType: Boolean) : IrB override fun IrDeclaration.isPlatformSpecificExported(): Boolean = isPlatformSpecificExport() } - private class KonanIrManglerComputer(builder: StringBuilder, mode: MangleMode, compatibleMode: Boolean, private val withReturnType: Boolean) : IrMangleComputer(builder, mode, compatibleMode) { - override fun copy(newMode: MangleMode): IrMangleComputer = KonanIrManglerComputer(builder, newMode, compatibleMode, withReturnType) + private class KonanIrManglerComputer( + builder: StringBuilder, + mode: MangleMode, + compatibleMode: Boolean, + private val withReturnType: Boolean, + allowOutOfScopeTypeParameters: Boolean, + ) : IrMangleComputer(builder, mode, compatibleMode, allowOutOfScopeTypeParameters) { + override fun copy(newMode: MangleMode): IrMangleComputer = + KonanIrManglerComputer(builder, newMode, compatibleMode, withReturnType, allowOutOfScopeTypeParameters) override fun addReturnType(): Boolean = withReturnType @@ -166,4 +177,4 @@ abstract class AbstractKonanDescriptorMangler : DescriptorBasedKotlinManglerImpl } } -object KonanManglerDesc : AbstractKonanDescriptorMangler() \ No newline at end of file +object KonanManglerDesc : AbstractKonanDescriptorMangler()