JVM: partially reify typeOf and signatures as soon as possible

E.g. when substituting T -> Array<T>, write the bytecode for the
Array<...> part for typeOf.

This fixes various issues where either Array nesting levels, nullability
information (for typeOf), or entire reification markers were missing,
causing incorrect outputs ranging from missing `?`s to missing `[]`s to
just reified types not really being reified.

^KT-53761 Fixed
This commit is contained in:
pyos
2022-08-30 12:15:40 +02:00
committed by Alexander Udalov
parent 2e6817042c
commit 8d33de4297
20 changed files with 363 additions and 223 deletions
@@ -57,7 +57,6 @@ import org.jetbrains.kotlin.types.computeExpandedTypeForInlineClass
import org.jetbrains.kotlin.types.model.TypeParameterMarker
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.kotlin.utils.keysToMap
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
@@ -1455,30 +1454,12 @@ class ExpressionCodegen(
if (element.typeArgumentsCount == 0) {
//avoid ambiguity with type constructor type parameters
emptyMap()
} else typeArgumentContainer.typeParameters.keysToMap {
element.getTypeArgumentOrDefault(it)
} else typeArgumentContainer.typeParameters.associate {
it.symbol to element.getTypeArgumentOrDefault(it)
}
val mappings = TypeParameterMappings<IrType>()
for ((key, type) in typeArguments.entries) {
val reificationArgument = typeMapper.typeSystem.extractReificationArgument(type)
if (reificationArgument == null) {
// type is not generic
val signatureWriter = BothSignatureWriter(BothSignatureWriter.Mode.TYPE)
val asmType = typeMapper.mapTypeParameter(type, signatureWriter)
mappings.addParameterMappingToType(
key.name.identifier, type, asmType, signatureWriter.toString(), key.isReified
)
} else {
mappings.addParameterMappingForFurtherReification(
key.name.identifier, type, reificationArgument.second, key.isReified
)
}
}
val mappings = TypeParameterMappings(typeMapper.typeSystem, typeArguments, allReified = false, typeMapper::mapTypeParameter)
val sourceCompiler = IrSourceCompilerForInline(state, element, callee, this, data)
val reifiedTypeInliner = ReifiedTypeInliner(
mappings,
IrInlineIntrinsicsSupport(classCodegen, element, irFunction.fileParent),
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo
import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
import org.jetbrains.kotlin.backend.jvm.codegen.IrInlineIntrinsicsSupport
import org.jetbrains.kotlin.backend.jvm.ir.fileParent
import org.jetbrains.kotlin.codegen.extractUsedReifiedParameters
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
import org.jetbrains.kotlin.codegen.inline.generateTypeOf
import org.jetbrains.kotlin.codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter
@@ -17,12 +18,9 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
object TypeOf : IntrinsicMethod() {
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo) = with(codegen) {
val type = expression.getTypeArgument(0)!!
if (putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.TYPE_OF)) {
mv.aconst(null) // see ReifiedTypeInliner.processTypeOf
} else {
val support = IrInlineIntrinsicsSupport(codegen.classCodegen, expression, codegen.irFunction.fileParent)
typeMapper.typeSystem.generateTypeOf(mv, type, support)
}
val support = IrInlineIntrinsicsSupport(codegen.classCodegen, expression, codegen.irFunction.fileParent)
typeMapper.typeSystem.generateTypeOf(mv, type, support)
codegen.propagateChildReifiedTypeParametersUsages(codegen.typeMapper.typeSystem.extractUsedReifiedParameters(type))
expression.onStack
}
}