JVM IR: substitute generic type for inline class replacement function calls

The main change here is in `JvmInlineClassLowering.visitFunctionAccess`,
where we now store the substituted return type of the function as the
type of the call expression. Without it, the call could have a
meaningless type, e.g. some `T` which is inaccessible at that place, and
that could backfire in subsequent lowerings in codegen. For example, in
the `stringPlus.kt` test, it would prevent the code in
`FlattenStringConcatenationLowering.isStringPlusCall` from recognizing
and replacing the `String.plus` call, leading to a codegen exception.

Other changes are mostly cosmetics to make the code similar to
`visitFunctionReference`, and preventive optimizations for the case when
the substitution map is empty.
This commit is contained in:
Alexander Udalov
2020-10-26 19:08:00 +01:00
parent 4a3a2ef72a
commit ad5b6da273
17 changed files with 73 additions and 37 deletions
@@ -16,7 +16,10 @@ 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.*
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.name.FqName
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.utils.DFS
@@ -512,10 +515,12 @@ val IrFunction.allTypeParameters: List<IrTypeParameter>
else
typeParameters
fun IrMemberAccessExpression<*>.getTypeSubstitutionMap(irFunction: IrFunction): Map<IrTypeParameterSymbol, IrType> =
irFunction.allTypeParameters.withIndex().associate {
fun IrMemberAccessExpression<*>.getTypeSubstitutionMap(irFunction: IrFunction): Map<IrTypeParameterSymbol, IrType> {
val typeParameters = irFunction.allTypeParameters
return if (typeParameters.isEmpty()) emptyMap() else typeParameters.withIndex().associate {
it.value.symbol to getTypeArgument(it.index)!!
}
}
val IrFunctionReference.typeSubstitutionMap: Map<IrTypeParameterSymbol, IrType>
get() = getTypeSubstitutionMap(symbol.owner)
@@ -536,4 +541,4 @@ val IrFunction.originalFunction: IrFunction
get() = (this as? IrAttributeContainer)?.attributeOwnerId as? IrFunction ?: this
val IrProperty.originalProperty: IrProperty
get() = attributeOwnerId as? IrProperty ?: this
get() = attributeOwnerId as? IrProperty ?: this