[JVM_IR] Determine correct type of empty varargs array.

When calling vararg methods with a generic vararg type without
passing explicit parameters, we have to allocate an empty array
of the right type. We failed to do so previously, as we did
not take the type arguments for the dispatch receiver into
account.
This commit is contained in:
Mads Ager
2020-10-29 08:10:39 +01:00
committed by Alexander Udalov
parent ffc003c051
commit 1ecf5943ab
9 changed files with 179 additions and 8 deletions
@@ -389,7 +389,6 @@ fun extractTypeParameters(klass: IrDeclarationParent): List<IrTypeParameter> {
val result = mutableListOf<IrTypeParameter>()
var current: IrDeclarationParent? = klass
while (current != null) {
// result += current.typeParameters
(current as? IrTypeParametersContainer)?.let { result += it.typeParameters }
current =
when (current) {
@@ -16,10 +16,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.isAny
import org.jetbrains.kotlin.ir.types.isSubtypeOf
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.utils.DFS
@@ -518,9 +515,24 @@ val IrFunction.allTypeParameters: List<IrTypeParameter>
else
typeParameters
fun IrMemberAccessExpression<*>.getTypeSubstitutionMap(irFunction: IrFunction): Map<IrTypeParameterSymbol, IrType> {
val typeParameters = irFunction.allTypeParameters
return if (typeParameters.isEmpty()) emptyMap() else typeParameters.withIndex().associate {
val dispatchReceiverTypeArguments = (dispatchReceiver?.type as? IrSimpleType)?.arguments ?: emptyList()
if (typeParameters.isEmpty() && dispatchReceiverTypeArguments.isEmpty()) {
return emptyMap()
}
val result = mutableMapOf<IrTypeParameterSymbol, IrType>()
if (dispatchReceiverTypeArguments.isNotEmpty()) {
val parentTypeParameters = extractTypeParameters(irFunction.parentClassOrNull!!)
parentTypeParameters.withIndex().forEach { (index, typeParam) ->
dispatchReceiverTypeArguments[index].typeOrNull?.let {
result[typeParam.symbol] = it
}
}
}
return typeParameters.withIndex().associateTo(result) {
it.value.symbol to getTypeArgument(it.index)!!
}
}