Refactoring: Improve createExpectActualTypeParameterSubstitutor API

Review: https://jetbrains.team/p/kt/reviews/12279/files

Motivation: make sure that cases like KT-62027 won't happen again
Review: https://jetbrains.team/p/kt/reviews/12279/files

Now it's responsibility of the
`createExpectActualTypeParameterSubstitutor` calller to think about the
case when parameters size isn't equal. You must not be able to create a
substitutor if type parameters sizes are not equal

Improvement in `createExpectActualTypeParameterSubstitutor` API also
improves
`AbstractExpectActualCompatibilityChecker.getCallablesCompatibility`
API.

Because suppose that you accidentally created a redundant wrapping
substitutor => you need to handle the case of not equal type parameters
size on the call site => you start thinking why you should do that on
the call site? It must be a responsibility of
`getCallablesCompatibility` => you realize that you created a redundant
wrapping substitutor
This commit is contained in:
Nikita Bobko
2023-09-20 14:17:59 +02:00
committed by Space Team
parent 211102569c
commit 91a337074e
12 changed files with 48 additions and 62 deletions
@@ -37,8 +37,6 @@ import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
import org.jetbrains.kotlin.types.model.TypeSystemContext
import org.jetbrains.kotlin.utils.addToStdlib.UnsafeCastFunction
import org.jetbrains.kotlin.utils.addToStdlib.castAll
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
internal abstract class IrExpectActualMatchingContext(
@@ -238,16 +236,14 @@ internal abstract class IrExpectActualMatchingContext(
override val PropertySymbolMarker.setter: FunctionSymbolMarker?
get() = asIr().setter?.symbol
@OptIn(UnsafeCastFunction::class)
override fun createExpectActualTypeParameterSubstitutor(
expectTypeParameters: List<TypeParameterSymbolMarker>,
actualTypeParameters: List<TypeParameterSymbolMarker>,
expectActualTypeParameters: List<Pair<TypeParameterSymbolMarker, TypeParameterSymbolMarker>>,
parentSubstitutor: TypeSubstitutorMarker?,
): TypeSubstitutorMarker {
val expectParameters = expectTypeParameters.castAll<IrTypeParameterSymbol>()
val actualParameters = actualTypeParameters.castAll<IrTypeParameterSymbol>()
val actualTypes = actualParameters.map { it.owner.defaultType }
val substitutor = IrTypeSubstitutor(expectParameters, actualTypes, allowEmptySubstitution = true)
val typeParametersToArguments = expectActualTypeParameters.associate { (expect, actual) ->
(expect as IrTypeParameterSymbol) to (actual as IrTypeParameterSymbol).owner.defaultType
}
val substitutor = IrTypeSubstitutor(typeParametersToArguments, allowEmptySubstitution = true)
return when (parentSubstitutor) {
null -> substitutor
is AbstractIrTypeSubstitutor -> IrChainedSubstitutor(parentSubstitutor, substitutor)
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.IrTypeArgument
import org.jetbrains.kotlin.ir.types.IrTypeSubstitutor
import org.jetbrains.kotlin.ir.util.SYNTHETIC_OFFSET
@@ -50,11 +51,8 @@ class WrapInlineDeclarationsWithReifiedTypeParametersLowering(val context: Backe
if (!owner.isInlineFunWithReifiedParameter()) {
return expression
}
val substitutionMap = expression.typeSubstitutionMap.entries
val typeSubstitutor = IrTypeSubstitutor(
substitutionMap.map { it.key },
substitutionMap.map { it.value as IrTypeArgument },
)
@Suppress("UNCHECKED_CAST")
val typeSubstitutor = IrTypeSubstitutor(expression.typeSubstitutionMap as Map<IrTypeParameterSymbol, IrTypeArgument>)
val function = irFactory.buildFun {
name = Name.identifier("${owner.name}${"$"}wrap")