Skip to content

Commit

Permalink
FIR2IR: Force using a vararg element type for substituted expected type
Browse files Browse the repository at this point in the history
It might change the semantics at insertCastToArgument, but:
- the new one looks more correct
- I didn't manage to invent the test which would change here

But the main reason for doing this is later work for unification
of implicit conversions between calls and other places.
  • Loading branch information
dzharkov authored and Space Team committed Feb 18, 2025
1 parent 9ffa053 commit f0b4ca7
Showing 1 changed file with 13 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1075,12 +1075,21 @@ class CallAndReferenceGenerator(
)

if (unsubstitutedParameterType != null) {
// Unsubstituted parameter type is only used for generating nullability check if the argument being used is flexible,
// while the value parameter doesn't accept nulls.
// And this is the only use case where the whole Array type is required for vararg, all other implicit coercion/conversion
// logic needs the element type and substituted type.
val substitutedParameterType = substitutor.substituteOrSelf(
when {
parameter.isVararg -> unsubstitutedParameterType.arrayElementType()!!
else -> unsubstitutedParameterType
}
)
with(visitor.implicitCastInserter) {
val argumentType = argument.resolvedType.fullyExpandedType(session)

fun insertCastToArgument(argument: FirExpression): IrExpression = when (argument) {
is FirSmartCastExpression -> {
val substitutedParameterType = substitutor.substituteOrSelf(unsubstitutedParameterType)
// here we should use a substituted parameter type to properly choose the component of an intersection type
// to provide a proper cast to the smartcasted type
irArgument.insertCastForSmartcastWithIntersection(argumentType, substitutedParameterType)
Expand All @@ -1091,18 +1100,16 @@ class CallAndReferenceGenerator(
else -> irArgument
}
irArgument = insertCastToArgument(argument)
// here we should pass unsubstituted parameter type to properly infer if the original type accepts null or not
// here we should pass an unsubstituted parameter type to properly infer if the original type accepts null or not
// to properly insert nullability check
irArgument = irArgument.insertSpecialCast(argument, argumentType, unsubstitutedParameterType)
}

with(adapterGenerator) {
val unwrappedParameterType =
if (parameter.isVararg) unsubstitutedParameterType.arrayElementType()!! else unsubstitutedParameterType
val samFunctionType = getFunctionTypeForPossibleSamType(unwrappedParameterType)
val samFunctionType = getFunctionTypeForPossibleSamType(substitutedParameterType)
irArgument = irArgument.applySuspendConversionIfNeeded(
argument,
substitutor.substituteOrSelf(samFunctionType ?: unwrappedParameterType)
samFunctionType ?: substitutedParameterType
)
irArgument = irArgument.applySamConversionIfNeeded(argument)
}
Expand Down

0 comments on commit f0b4ca7

Please sign in to comment.