Set receivers for inline class default function stub calls

Default function stubs have dispatch and receiver parameters, but
inline class methods are static by design with receivers as ordinary
parameters. So, take these parameters and set them as receivers during
lowerings.
 #KT-46230: Fixed
This commit is contained in:
Ilmir Usmanov
2021-07-08 04:01:59 +02:00
committed by teamcityserver
parent 31420a934c
commit ac7538a269
15 changed files with 332 additions and 7 deletions
@@ -303,17 +303,30 @@ open class DefaultParameterInjector(
}
symbol.owner.typeParameters.forEach { log { "${symbol.owner}[${it.index}] : $it" } }
val isStatic = isStatic(expression.symbol.owner)
return builder(symbol).apply {
copyTypeArgumentsFrom(expression)
params.forEachIndexed { i, value ->
var receivers = 0
if (isStatic) {
if (symbol.owner.dispatchReceiverParameter != null) {
dispatchReceiver = params[receivers++]
}
if (symbol.owner.extensionReceiverParameter != null) {
extensionReceiver = params[receivers++]
}
} else {
dispatchReceiver = expression.dispatchReceiver
extensionReceiver = expression.extensionReceiver
}
params.drop(receivers).forEachIndexed { i, value ->
log { "call::params@$i/${symbol.owner.valueParameters[i].name}: ${ir2string(value)}" }
putValueArgument(i, value)
}
dispatchReceiver = expression.dispatchReceiver
extensionReceiver = expression.extensionReceiver
log { "call::extension@: ${ir2string(expression.extensionReceiver)}" }
log { "call::dispatch@: ${ir2string(expression.dispatchReceiver)}" }
}
@@ -393,12 +406,19 @@ open class DefaultParameterInjector(
val realArgumentsNumber = declaration.valueParameters.size
val maskValues = IntArray((declaration.valueParameters.size + 31) / 32)
assert((stubFunction.valueParameters.size - realArgumentsNumber - maskValues.size) in listOf(0, 1)) {
assert(
((if (isStatic(expression.symbol.owner) && stubFunction.extensionReceiverParameter != null) 1 else 0) +
stubFunction.valueParameters.size - realArgumentsNumber - maskValues.size) in listOf(0, 1)
) {
"argument count mismatch: expected $realArgumentsNumber arguments + ${maskValues.size} masks + optional handler/marker, " +
"got ${stubFunction.valueParameters.size} total in ${stubFunction.render()}"
}
var sourceParameterIndex = -1
return stubFunction.symbol to stubFunction.valueParameters.mapIndexed { i, parameter ->
val valueParametersPrefix =
if (isStatic(expression.symbol.owner))
listOfNotNull(stubFunction.dispatchReceiverParameter, stubFunction.extensionReceiverParameter)
else emptyList()
return stubFunction.symbol to (valueParametersPrefix + stubFunction.valueParameters).mapIndexed { i, parameter ->
if (!parameter.isMovedReceiver()) {
++sourceParameterIndex
}
@@ -438,6 +458,8 @@ open class DefaultParameterInjector(
protected open fun useConstructorMarker(function: IrFunction) = function is IrConstructor
protected open fun isStatic(function: IrFunction): Boolean = false
private fun log(msg: () -> String) = context.log { "DEFAULT-INJECTOR: ${msg()}" }
}