[FIR] Fix handling of type parameters in FIR mangling

#KT-57429 Fixed
This commit is contained in:
Kirill Rakhman
2023-06-05 17:31:27 +02:00
committed by Space Team
parent 938dd65881
commit 67fc46a190
48 changed files with 199 additions and 141 deletions
@@ -33,28 +33,6 @@ class FirJvmMangleComputer(
override fun copy(newMode: MangleMode): FirJvmMangleComputer =
FirJvmMangleComputer(builder, newMode)
// FIXME this implementation causes the mangler to deliver different result than IR mangler. Consider using base method instead
override fun getEffectiveParent(typeParameter: ConeTypeParameterLookupTag): FirMemberDeclaration = typeParameter.symbol.fir.run {
fun FirTypeParameter.sameAs(other: FirTypeParameter) =
this === other ||
(name == other.name && bounds.size == other.bounds.size &&
bounds.zip(other.bounds).all { it.first.coneType == it.second.coneType })
for (parent in typeParameterContainers) {
if (parent.typeParameters.any { this.sameAs(it.symbol.fir) }) {
return parent
}
if (parent is FirCallableDeclaration) {
val overriddenFir = parent.originalForSubstitutionOverride
if (overriddenFir is FirTypeParametersOwner && overriddenFir.typeParameters.any { this.sameAs(it) }) {
return parent
}
}
}
throw IllegalStateException("Should not be here!")
}
private inner class JvmVisitor : Visitor() {
override fun visitField(field: FirField) {
if (field is FirJavaField) {
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.backend.common.serialization.mangle.collectForMangle
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
@@ -108,8 +107,17 @@ open class FirMangleComputer(
override fun isUnit(type: ConeKotlinType) = type.isUnit
@OptIn(SymbolInternals::class)
override fun getEffectiveParent(typeParameter: ConeTypeParameterLookupTag): FirMemberDeclaration = typeParameter.symbol.fir.run {
this.containingDeclarationSymbol.fir as FirMemberDeclaration
override fun getEffectiveParent(typeParameter: ConeTypeParameterLookupTag): FirMemberDeclaration =
typeParameter.symbol.containingDeclarationSymbol.fir as FirMemberDeclaration
override fun getContainerIndex(parent: FirMemberDeclaration): Int {
// If a type parameter is declared in a java method, typeParameterContainers will contain the enhanced declaration,
// but parent will be the non-enhanced version.
// To work around this, we additionally compare declarations using their callable IDs.
val callableId = (parent as? FirCallableDeclaration)?.symbol?.callableId
return typeParameterContainers.indexOfFirst {
it == parent || it is FirCallableDeclaration && it.symbol.callableId == callableId
}
}
override fun renderDeclaration(declaration: FirDeclaration) = declaration.render()
@@ -279,4 +287,4 @@ open class FirMangleComputer(
}
}
}
}
}
@@ -219,7 +219,7 @@ abstract class BaseKotlinMangleComputer<Declaration, Type, TypeParameter, ValueP
protected fun StringBuilder.mangleTypeParameterReference(typeParameter: TypeParameter) {
val parent = getEffectiveParent(typeParameter)
val containerIndex = typeParameterContainers.indexOf(parent)
val containerIndex = getContainerIndex(parent)
require(allowOutOfScopeTypeParameters || containerIndex >= 0) {
"No container found for type parameter '${getTypeParameterName(typeParameter)}' of '${renderDeclaration(parent)}'"
}
@@ -228,6 +228,9 @@ abstract class BaseKotlinMangleComputer<Declaration, Type, TypeParameter, ValueP
appendSignature(getIndexOfTypeParameter(typeParameter, parent))
}
protected open fun getContainerIndex(parent: TypeParameterContainer): Int {
return typeParameterContainers.indexOf(parent)
}
protected fun mangleTypeParameter(
tpBuilder: StringBuilder,
@@ -1,6 +1,3 @@
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
data class Test1(
val stringArray: Array<String>,
val charArray: CharArray,
@@ -1,6 +1,3 @@
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
data class Test1<T>(val x: T)
data class Test2<T : Number>(val x: T)
@@ -1,6 +1,3 @@
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
open class Cell<T>(val value: T)
typealias CT<T> = Cell<T>
@@ -1,8 +1,5 @@
// !LANGUAGE: +InlineClasses
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
class C<T>(val t: T) {
override fun hashCode(): Int = t as Int
}
@@ -1,5 +1,5 @@
// SKIP_SIGNATURE_DUMP
// ^ KT-57429, different types in annotations generated by K1 and K2
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-54517
package ann
@@ -0,0 +1,162 @@
package ann
// CHECK:
// Mangled name: ann.Test1
// Public signature: ann/Test1|null[0]
open annotation class Test1<T : Any?> : Annotation {
// CHECK:
// Mangled name: ann.Test1{}x
// Public signature: ann/Test1.x|-8060530855978347579[0]
val x: Int
// CHECK JVM_IR:
// Mangled name: ann.Test1#<get-x>(){}kotlin.Int
// Public signature: ann/Test1.x.<get-x>|4966956098150895696[0]
// CHECK JS_IR:
// Mangled name: ann.Test1#<get-x>(){}
// Public signature: ann/Test1.x.<get-x>|1482705010654679335[0]
get
// CHECK:
// Mangled name: ann.Test1#<init>(kotlin.Int){}
// Public signature: ann/Test1.<init>|-5182794243525578284[0]
constructor(x: Int) /* primary */
}
// CHECK:
// Mangled name: ann.Test2
// Public signature: ann/Test2|null[0]
open annotation class Test2<T1 : Any, T2 : Any?> : Annotation {
// CHECK:
// Mangled name: ann.Test2{}x
// Public signature: ann/Test2.x|-8060530855978347579[0]
val x: Int
// CHECK JVM_IR:
// Mangled name: ann.Test2#<get-x>(){}kotlin.Int
// Public signature: ann/Test2.x.<get-x>|4966956098150895696[0]
// CHECK JS_IR:
// Mangled name: ann.Test2#<get-x>(){}
// Public signature: ann/Test2.x.<get-x>|1482705010654679335[0]
get
// CHECK:
// Mangled name: ann.Test2#<init>(kotlin.Int){}
// Public signature: ann/Test2.<init>|-5182794243525578284[0]
constructor(x: Int) /* primary */
}
// CHECK:
// Mangled name: ann.Test3
// Public signature: ann/Test3|null[0]
open annotation class Test3<T1 : Any?, T2 : I<T1>> : Annotation {
// CHECK:
// Mangled name: ann.Test3{}x
// Public signature: ann/Test3.x|-8060530855978347579[0]
val x: Test1<I<T2>>
// CHECK JVM_IR:
// Mangled name: ann.Test3#<get-x>(){}ann.Test1<ann.I<1:1>>
// Public signature: ann/Test3.x.<get-x>|-476605448158023096[0]
// CHECK JS_IR:
// Mangled name: ann.Test3#<get-x>(){}
// Public signature: ann/Test3.x.<get-x>|1482705010654679335[0]
get
// CHECK:
// Mangled name: ann.Test3#<init>(ann.Test1<ann.I<1:1>>){}
// Public signature: ann/Test3.<init>|-7213108781936914004[0]
constructor(x: Test1<I<T2>>) /* primary */
}
// CHECK:
// Mangled name: ann.Test4
// Public signature: ann/Test4|null[0]
open annotation class Test4 : Annotation {
// CHECK:
// Mangled name: ann.Test4{}x
// Public signature: ann/Test4.x|-8060530855978347579[0]
val x: Array<Test3<Int, C<Int>>>
// CHECK JVM_IR:
// Mangled name: ann.Test4#<get-x>(){}kotlin.Array<ann.Test3<kotlin.Int,ann.C<kotlin.Int>>>
// Public signature: ann/Test4.x.<get-x>|-4754126975303916738[0]
// CHECK JS_IR:
// Mangled name: ann.Test4#<get-x>(){}
// Public signature: ann/Test4.x.<get-x>|1482705010654679335[0]
get
// CHECK:
// Mangled name: ann.Test4#<init>(kotlin.Array<ann.Test3<kotlin.Int,ann.C<kotlin.Int>>>){}
// Public signature: ann/Test4.<init>|8552260922942750189[0]
constructor(x: Array<Test3<Int, C<Int>>>) /* primary */
}
// CHECK:
// Mangled name: ann.Test5
// Public signature: ann/Test5|null[0]
open annotation class Test5<T : Any?> : Annotation {
// CHECK:
// Mangled name: ann.Test5{}xs
// Public signature: ann/Test5.xs|1063330853857063704[0]
val xs: Array<out Test3<T, C<T>>>
// CHECK JVM_IR:
// Mangled name: ann.Test5#<get-xs>(){}kotlin.Array<out|ann.Test3<1:0,ann.C<1:0>>>
// Public signature: ann/Test5.xs.<get-xs>|-4480240150602494549[0]
// CHECK JS_IR:
// Mangled name: ann.Test5#<get-xs>(){}
// Public signature: ann/Test5.xs.<get-xs>|-6958094100501701183[0]
get
// CHECK:
// Mangled name: ann.Test5#<init>(kotlin.Array<out|ann.Test3<1:0,ann.C<1:0>>>...){}
// Public signature: ann/Test5.<init>|4580033169902184740[0]
constructor(vararg xs: Test3<T, C<T>>) /* primary */
}
// CHECK:
// Mangled name: ann.ARG
// Public signature: ann/ARG|null[0]
class ARG {
// CHECK:
// Mangled name: ann.ARG#<init>(){}
// Public signature: ann/ARG.<init>|-5645683436151566731[0]
constructor() /* primary */
}
// CHECK:
// Mangled name: ann.C
// Public signature: ann/C|null[0]
class C<T : Any?> : I<T> {
// CHECK:
// Mangled name: ann.C#<init>(){}
// Public signature: ann/C.<init>|-5645683436151566731[0]
constructor() /* primary */
}
// CHECK:
// Mangled name: ann.CC
// Public signature: ann/CC|null[0]
@Test1<ARG>(x = 42)
@Test2<String, String>(x = 38)
@Test3<String, C<String>>(x = Test1<I<C<String>>>(x = 39))
@Test4(x = [Test3<Int, C<Int>>(x = Test1<I<C<Int>>>(x = 40)), Test3<Int, C<Int>>(x = Test1<I<C<Int>>>(x = 50)), Test3<Int, C<Int>>(x = Test1<I<C<Int>>>(x = 60))])
@Test5<ARG>(xs = [[Test3<ARG, C<ARG>>(x = Test1<I<C<ARG>>>(x = 70))], [Test3<ARG, C<ARG>>(x = Test1<I<C<ARG>>>(x = 80))]])
class CC {
// CHECK:
// Mangled name: ann.CC#<init>(){}
// Public signature: ann/CC.<init>|-5645683436151566731[0]
constructor() /* primary */
}
// CHECK:
// Mangled name: ann.I
// Public signature: ann/I|null[0]
interface I<T : Any?> {
}
@@ -1,9 +1,6 @@
// !LANGUAGE: +ContextReceivers
// IGNORE_BACKEND: JS_IR
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57429
data class Pair<A, B>(val first: A, val second: B)
context(Comparator<T>)
@@ -1,9 +1,6 @@
// FIR_IDENTICAL
// !LANGUAGE: +ContextReceivers
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
context(T) class A<T>
context(Collection<P>) class B<P>
@@ -1,9 +1,6 @@
// FIR_IDENTICAL
// !LANGUAGE: +ContextReceivers
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
class A<T>(val a: T)
class B(val b: Any)
class C(val c: Any)
@@ -1,6 +1,3 @@
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
class Test1<T1, T2>(val x: T1, val y: T2)
class Test2(x: Int, val y: String) {
@@ -1,4 +1 @@
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
data class Test<T>(val x: T, val y: String = "")
@@ -1,8 +1,5 @@
// FIR_IDENTICAL
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
val test1 = 42
var test2 = 42
@@ -1,5 +1,5 @@
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57754, KT-57429
// ^ KT-57754
interface IBase<T> {
fun foo(x: Int)
@@ -1,8 +1,5 @@
// FIR_IDENTICAL
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
class Outer<T1> {
inner class Inner<T2> {
fun foo(x1: T1, x2: T2) {}
@@ -1,8 +1,5 @@
// FIR_IDENTICAL
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
package test
class Foo<T> {
@@ -1,6 +1,3 @@
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
open class L<LL>(val ll: LL)
class Rec<T>(val rt: T)
@@ -1,6 +1,3 @@
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
fun testSimple() = Box<Long>(2L * 3)
inline fun <reified T> testArray(n: Int, crossinline block: () -> T): Array<T> {
@@ -1,6 +1,3 @@
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
class Value<T>(var value: T = null as T, var text: String? = null)
val <T> Value<T>.additionalText by DVal(Value<T>::text)
-3
View File
@@ -1,6 +1,3 @@
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
class A<T>(private val value: T) {
operator fun get(i: Int) = value
operator fun set(i: Int, v: T) {}
-3
View File
@@ -3,9 +3,6 @@
// WITH_STDLIB
// SKIP_KT_DUMP
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57429
// FILE: kt44993.kt
fun f(r: KotlinBox<JavaBox>): String =
r?.data?.element!!
-3
View File
@@ -6,9 +6,6 @@
// TARGET_BACKEND: JVM_IR
// WITH_STDLIB
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57429
interface A { val x: Int }
class B(@JvmField override val x: Int): A
@@ -1,8 +1,5 @@
// FIR_IDENTICAL
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
class GenericClass<T>(val value: T) {
fun withNewValue(newValue: T) = GenericClass(newValue)
}
@@ -1,9 +1,6 @@
// FIR_IDENTICAL
// TARGET_BACKEND: JVM
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57429
// FILE: samConversionInGenericConstructorCall.kt
fun test3(
f1: (String) -> String,
@@ -1,6 +1,3 @@
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
class Cell<T>(val value: T)
typealias IntAlias = Cell<Int>
@@ -1,6 +1,3 @@
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
class Outer<T>(val x: T) {
open inner class Inner(val y: Int)
}
-3
View File
@@ -3,9 +3,6 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57429
sealed class ArrayMap<T : Any> : Iterable<T> {
abstract val size: Int
@@ -3,7 +3,7 @@
// WITH_STDLIB
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57429
// ^ KT-57778
import java.lang.reflect.Type
@@ -5,7 +5,7 @@
// IGNORE_BACKEND: JS_IR_ES6
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57429, KT-57788
// ^ KT-57788
interface SymbolOwner<E : SymbolOwner<E>>
-3
View File
@@ -1,8 +1,5 @@
// TARGET_BACKEND: JVM
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57429
// FILE: Foo.java
public class Foo {
@@ -1,7 +1,7 @@
// TARGET_BACKEND: JVM_IR
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57429
// ^ KT-57022
// FILE: J.java
@@ -1,8 +1,5 @@
// ISSUE: KT-58008
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
object Retry {
class Builder<B>(
private val action: suspend () -> B,
-3
View File
@@ -2,9 +2,6 @@
// IGNORE_BACKEND_K2: JS_IR
// IGNORE_BACKEND_K2: JS_IR_ES6
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57429
open class ControlFlowInfo<K, V>(val map: Map<K, V>): Map<K, V> by map
class StringFlowInfo(map: Map<String, String>): ControlFlowInfo<String, String>(map) {
@@ -3,7 +3,7 @@
// DUMP_LOCAL_DECLARATION_SIGNATURES
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57429, KT-57430
// ^ KT-57430
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KClass
-3
View File
@@ -2,9 +2,6 @@
// SKIP_KT_DUMP
// TARGET_BACKEND: JVM_IR
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57429
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
@@ -1,6 +1,3 @@
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
class A<Q>(val q: Q)
typealias B<X> = A<X>
@@ -1,9 +1,6 @@
// IGNORE_BACKEND_K1: JS_IR
// IGNORE_BACKEND_K1: JS_IR_ES6
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57429
// MODULE: m1
// FILE: genericClassInDifferentModule_m1.kt
@@ -78,6 +78,9 @@ class Derived1<T : Any?> : Base<T> {
// CHECK JVM_IR:
// Mangled name: Derived1#<get-bar>(){}1:0
// Public signature: /Derived1.bar.<get-bar>|7899956589744407340[0]
// CHECK JS_IR:
// Mangled name: Derived1#<get-bar>(){}
// Public signature: /Derived1.bar.<get-bar>|6880642144337645699[0]
override get
// CHECK:
// Mangled name: Derived1#<set-bar>(1:0){}
@@ -92,6 +95,9 @@ class Derived1<T : Any?> : Base<T> {
// CHECK JVM_IR:
// Mangled name: Derived1#foo(0:0){0§<kotlin.Any?>}1:0
// Public signature: /Derived1.foo|8673945311830780726[0]
// CHECK JS_IR:
// Mangled name: Derived1#foo(0:0){0§<kotlin.Any?>}
// Public signature: /Derived1.foo|-6838606926256314363[0]
override fun <Y : Any?> foo(y: Y): T
// CHECK:
@@ -101,6 +107,9 @@ class Derived1<T : Any?> : Base<T> {
// CHECK JVM_IR:
// Mangled name: Derived1#<get-x>(){}1:0
// Public signature: /Derived1.x.<get-x>|-8893883356128097563[0]
// CHECK JS_IR:
// Mangled name: Derived1#<get-x>(){}
// Public signature: /Derived1.x.<get-x>|1482705010654679335[0]
/* fake */ override get(): T
// CHECK:
@@ -110,6 +119,9 @@ class Derived1<T : Any?> : Base<T> {
// CHECK JVM_IR:
// Mangled name: Derived1#<get-exn>@0:0(){0§<kotlin.Any?>}1:0
// Public signature: /Derived1.exn.<get-exn>|6217753676739394662[0]
// CHECK JS_IR:
// Mangled name: Derived1#<get-exn>@0:0(){0§<kotlin.Any?>}
// Public signature: /Derived1.exn.<get-exn>|-202876889853335253[0]
override get(): T
// CHECK:
// Mangled name: Derived1#<set-exn>@0:0(1:0){0§<kotlin.Any?>}
@@ -1,7 +1,7 @@
// WITH_STDLIB
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57429, KT-57778
// ^ KT-57778
import kotlin.experimental.ExperimentalTypeInference
@@ -1,8 +1,5 @@
//!LANGUAGE: +DefinitelyNonNullableTypes
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
interface I<T> {
fun input(t: T)
fun output(): T
@@ -2,7 +2,7 @@
// WITH_STDLIB
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429, KT-57755
// ^KT-57755
class Foo<T>(var x: T)
@@ -1,8 +1,5 @@
// !LANGUAGE: -ForbidUsingExtensionPropertyTypeParameterInDelegate
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
import kotlin.reflect.KProperty1
import kotlin.reflect.KMutableProperty1
import kotlin.reflect.KProperty
@@ -1,8 +1,5 @@
// FIR_IDENTICAL
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429, KT-57427
import kotlin.reflect.KMutableProperty
class C<T>(var x: T)
@@ -1,9 +1,6 @@
// TARGET_BACKEND: JVM
// WITH_STDLIB
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57429
// FILE: enhancedNullabilityInDestructuringAssignment.kt
fun use(x: Any, y: Any) {}
@@ -1,8 +1,5 @@
// FIR_IDENTICAL
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57429
fun testFunction(a: Any, b: Any) {
a as MutableList<String>
b as String
@@ -1,9 +1,6 @@
// KT-42036
// IGNORE_BACKEND: JS_IR
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57429
typealias Action<RenderingT> = (@UnsafeVariance RenderingT) -> Unit
data class Tag<out RenderingT>(val action: Action<RenderingT>)