diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt index 50cbd5074bd..487e9197bb8 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt @@ -611,8 +611,11 @@ class CallAndReferenceGenerator( } } for ((index, argument) in call.arguments.withIndex()) { + val valueParameter = valueParameters?.get(index) val argumentExpression = - visitor.convertToIrExpression(argument).applySamConversionIfNeeded(argument, valueParameters?.get(index)) + visitor.convertToIrExpression(argument) + .applySamConversionIfNeeded(argument, valueParameter) + .applyAssigningArrayElementsToVarargInNamedForm(argument, valueParameter) putValueArgument(index, argumentExpression) } } @@ -650,7 +653,10 @@ class CallAndReferenceGenerator( return IrBlockImpl(startOffset, endOffset, type, IrStatementOrigin.ARGUMENTS_REORDERING_FOR_CALL).apply { for ((argument, parameter) in argumentMapping) { val parameterIndex = valueParameters.indexOf(parameter) - val irArgument = visitor.convertToIrExpression(argument).applySamConversionIfNeeded(argument, parameter) + val irArgument = + visitor.convertToIrExpression(argument) + .applySamConversionIfNeeded(argument, parameter) + .applyAssigningArrayElementsToVarargInNamedForm(argument, parameter) if (irArgument.hasNoSideEffects()) { putValueArgument(parameterIndex, irArgument) } else { @@ -668,6 +674,7 @@ class CallAndReferenceGenerator( val argumentExpression = visitor.convertToIrExpression(argument, annotationMode) .applySamConversionIfNeeded(argument, parameter) + .applyAssigningArrayElementsToVarargInNamedForm(argument, parameter) putValueArgument(valueParameters.indexOf(parameter), argumentExpression) } if (annotationMode) { @@ -721,6 +728,30 @@ class CallAndReferenceGenerator( return argument.isFunctional(session) } + private fun IrExpression.applyAssigningArrayElementsToVarargInNamedForm( + argument: FirExpression, + parameter: FirValueParameter? + ): IrExpression { + // TODO: Need to refer to language feature: AllowAssigningArrayElementsToVarargsInNamedFormForFunctions + if (this !is IrVarargImpl || + parameter?.isVararg != true || + argument !is FirVarargArgumentsExpression || + argument.arguments.none { it is FirNamedArgumentExpression } + ) { + return this + } + elements.forEachIndexed { i, irVarargElement -> + if (irVarargElement !is IrSpreadElement && + argument.arguments[i] is FirNamedArgumentExpression && + irVarargElement is IrExpression && + irVarargElement.type.isArray() + ) { + elements[i] = IrSpreadElementImpl(irVarargElement.startOffset, irVarargElement.endOffset, irVarargElement) + } + } + return this + } + private fun IrExpression.applyTypeArguments(access: FirQualifiedAccess): IrExpression { return when (this) { is IrMemberAccessExpression<*> -> { diff --git a/compiler/testData/codegen/box/vararg/kt37779.kt b/compiler/testData/codegen/box/vararg/kt37779.kt index d187e212f83..cdb4361e562 100644 --- a/compiler/testData/codegen/box/vararg/kt37779.kt +++ b/compiler/testData/codegen/box/vararg/kt37779.kt @@ -1,5 +1,4 @@ // !LANGUAGE: +AllowAssigningArrayElementsToVarargsInNamedFormForFunctions -// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND: JS fun test(vararg s: String) = s[1] diff --git a/compiler/testData/ir/irText/expressions/kt37779.fir.txt b/compiler/testData/ir/irText/expressions/kt37779.fir.txt deleted file mode 100644 index aff9c793413..00000000000 --- a/compiler/testData/ir/irText/expressions/kt37779.fir.txt +++ /dev/null @@ -1,19 +0,0 @@ -FILE fqName: fileName:/kt37779.kt - FUN name:foo visibility:public modality:FINAL <> (s:kotlin.Array) returnType:kotlin.Unit - VALUE_PARAMETER name:s index:0 type:kotlin.Array varargElementType:kotlin.String [vararg] - BLOCK_BODY - FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit - BLOCK_BODY - CALL 'public final fun foo (vararg s: kotlin.String): kotlin.Unit declared in ' type=kotlin.Unit origin=null - s: VARARG type=kotlin.Array varargElementType=kotlin.String - CALL 'public final fun arrayOf (vararg elements: T of kotlin.arrayOf): kotlin.Array [inline] declared in kotlin' type=kotlin.Array origin=null - : kotlin.String - elements: VARARG type=kotlin.Array varargElementType=kotlin.String - CONST String type=kotlin.String value="" - CONST String type=kotlin.String value="OK" - FUN name:test2 visibility:public modality:FINAL <> (ss:kotlin.Array) returnType:kotlin.Unit - VALUE_PARAMETER name:ss index:0 type:kotlin.Array - BLOCK_BODY - CALL 'public final fun foo (vararg s: kotlin.String): kotlin.Unit declared in ' type=kotlin.Unit origin=null - s: VARARG type=kotlin.Array varargElementType=kotlin.String - GET_VAR 'ss: kotlin.Array declared in .test2' type=kotlin.Array origin=null diff --git a/compiler/testData/ir/irText/expressions/kt37779.kt b/compiler/testData/ir/irText/expressions/kt37779.kt index 94a1899c346..e8c8f8a0fc3 100644 --- a/compiler/testData/ir/irText/expressions/kt37779.kt +++ b/compiler/testData/ir/irText/expressions/kt37779.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !LANGUAGE: +AllowAssigningArrayElementsToVarargsInNamedFormForFunctions fun foo(vararg s: String) {}