Take into account 'KTypeImpl.classifier' in its hashCode and equals
Since KT-53308, we started to cache results of typeOf invocation in reflection. The cache uses the origin 'KClassifier' as a key with an optional list of 'KTypeProjection' in type argument position, and computed result as a value. Without classifier check, the caching produces incorrect execution in a very specific classloaders usage which is leveraged by IDEA source-tree: * All Kotlin stdlib and reflect classes are always loaded by the same classloader * Other classes that depend on Kotlin are loaded by separate classloaders The reproducer: * Attempt to use typeOf<kotlin.List<Foo>> from one classloader caches the resulting KType * Attempt to use typeOf<kotlin.List<Foo>> from another classloader for the same 'Foo' that differs only in classloader reuses the computed KType, meaning that KType type argument classifier is simply incorrect and points to the 'Foo' from the first classloader #KT-54611 Fixed #KT-54629 Fixed Merge-request: KT-MR-7470 Merged-by: Vsevolod Tolstopyatov <qwwdfsad@gmail.com>
This commit is contained in:
committed by
Space Team
parent
c098ba789c
commit
b29309478e
@@ -0,0 +1,25 @@
|
||||
package test
|
||||
|
||||
import kotlin.reflect.*
|
||||
import kotlin.reflect.full.*
|
||||
import kotlin.test.*
|
||||
|
||||
class K {
|
||||
fun getType() = typeOf<List<K>>()
|
||||
}
|
||||
|
||||
class Test {
|
||||
fun kClass(): Any = K::class
|
||||
|
||||
fun KClass<*>.invokeGetType() =
|
||||
java.declaredMethods.single { it.name == "getType" }.invoke(java.getDeclaredConstructor().newInstance()) as KType
|
||||
|
||||
fun doTest(k1: KClass<*>, k2: KClass<*>) {
|
||||
assertNotEquals(k1, k2)
|
||||
|
||||
val type1 = k1.invokeGetType()
|
||||
val type2 = k2.invokeGetType()
|
||||
assertNotEquals((type1.arguments[0].type)?.classifier, (type2.arguments[0].type)?.classifier)
|
||||
assertNotEquals(type1, type2)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user