From 9b53cded944ad2b29a2c043fec8b5092e64453d2 Mon Sep 17 00:00:00 2001 From: SvyatoslavScherbina Date: Thu, 15 Oct 2020 10:22:18 +0300 Subject: [PATCH] Fix secondary constructors of generic inline classes #KT-42649 Fixed. --- .../kotlin/backend/konan/lower/Autoboxing.kt | 9 ++++++++- backend.native/tests/build.gradle | 4 ++++ .../secondaryConstructorWithGenerics.kt | 18 ++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 backend.native/tests/codegen/inlineClass/secondaryConstructorWithGenerics.kt diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/Autoboxing.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/Autoboxing.kt index 055af9dbad7..57d7dbb9e7a 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/Autoboxing.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/Autoboxing.kt @@ -519,6 +519,13 @@ private val Context.getLoweredInlineClassConstructor: (IrConstructor) -> IrSimpl ).apply { descriptor.bind(this) parent = irConstructor.parent - valueParameters += irConstructor.valueParameters.map { it.copyTo(this) } + + // Note: technically speaking, this function doesn't have access to class type parameters (since it is "static"). + // But, technically speaking, otherwise we would have to remap types in the entire IR subtree, + // which is an overkill here, because type parameters don't matter at this phase of compilation and later. + // So it is just a trick to make [copyTo] happy: + val remapTypeMap = irConstructor.constructedClass.typeParameters.associateBy { it } + + valueParameters += irConstructor.valueParameters.map { it.copyTo(this, remapTypeMap = remapTypeMap) } } } diff --git a/backend.native/tests/build.gradle b/backend.native/tests/build.gradle index 06dd86449dd..a7a2e03ec9b 100644 --- a/backend.native/tests/build.gradle +++ b/backend.native/tests/build.gradle @@ -3172,6 +3172,10 @@ task inlineClass_defaultEquals(type: KonanLocalTest) { source = "codegen/inlineClass/defaultEquals.kt" } +task inlineClass_secondaryConstructorWithGenerics(type: KonanLocalTest) { + source = "codegen/inlineClass/secondaryConstructorWithGenerics.kt" +} + task deserialized_inline0(type: KonanLocalTest) { source = "serialization/deserialized_inline0.kt" } diff --git a/backend.native/tests/codegen/inlineClass/secondaryConstructorWithGenerics.kt b/backend.native/tests/codegen/inlineClass/secondaryConstructorWithGenerics.kt new file mode 100644 index 00000000000..8bef556cfab --- /dev/null +++ b/backend.native/tests/codegen/inlineClass/secondaryConstructorWithGenerics.kt @@ -0,0 +1,18 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +package codegen.inlineClass.secondaryConstructorWithGenerics + +import kotlin.test.* + +// Based on KT-42649. +inline class IC(val value: List) { + constructor(value: T) : this(listOf(value)) +} + +@Test +fun runTest() { + assertEquals("abc", IC("abc").value.singleOrNull()) +}