[JVM] Make IR interpreter resilient to enhanced nullability. Google uses jspecify annotations on core Java classes such as `Boolean`. This trips up the IR interpreter for any use of constants such as `java.lang.Boolean.TRUE`. The IR interpreter trusts the enhanced nullability information and uses reflection to try to load a field of primitive type instead of object type. This change loads nullability enhanced fields with object type in the IR interpreter. ^KT-62789 Fixed
diff --git a/compiler/ir/ir.interpreter/build.gradle.kts b/compiler/ir/ir.interpreter/build.gradle.kts index db7fc1a..a0657d1 100644 --- a/compiler/ir/ir.interpreter/build.gradle.kts +++ b/compiler/ir/ir.interpreter/build.gradle.kts
@@ -5,6 +5,7 @@ dependencies { compileOnly(project(":compiler:ir.tree")) + compileOnly(project(":core:compiler.common.jvm")) compileOnly(commonDependency("org.jetbrains.kotlin:kotlin-reflect")) { isTransitive = false } }
diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Wrapper.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Wrapper.kt index 5437f0c..c828cbc 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Wrapper.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Wrapper.kt
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly import java.lang.invoke.MethodHandle import java.lang.invoke.MethodHandles @@ -176,7 +177,9 @@ fun getStaticGetter(field: IrField): MethodHandle { val jvmClass = field.parentAsClass.defaultType.getClass(true) - val returnType = field.type.let { it.getClass(it.isNullable()) } + val getAsObjectType = field.type.isNullable() || + field.type.hasAnnotation(JvmAnnotationNames.ENHANCED_NULLABILITY_ANNOTATION) + val returnType = field.type.getClass(getAsObjectType) return MethodHandles.lookup().findStaticGetter(jvmClass, field.name.asString(), returnType) }