diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirArgumentsToParametersMapper.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirArgumentsToParametersMapper.kt index bf0864b8064..fcdef0b3542 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirArgumentsToParametersMapper.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirArgumentsToParametersMapper.kt @@ -6,11 +6,14 @@ package org.jetbrains.kotlin.fir.resolve.calls import org.jetbrains.kotlin.fir.declarations.FirFunction +import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction import org.jetbrains.kotlin.fir.declarations.FirValueParameter +import org.jetbrains.kotlin.fir.declarations.isOperator import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirLambdaArgumentExpression import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression import org.jetbrains.kotlin.fir.expressions.FirSpreadArgumentExpression +import org.jetbrains.kotlin.fir.expressions.builder.buildNamedArgumentExpression import org.jetbrains.kotlin.name.Name import java.util.* import kotlin.collections.ArrayList @@ -50,12 +53,30 @@ fun mapArguments( return EmptyArgumentMapping } val externalArgument: FirExpression? = arguments.lastOrNull { it is FirLambdaArgumentExpression } - val argumentsInParenthesis: List = if (externalArgument == null) { + var argumentsInParenthesis: List = if (externalArgument == null) { arguments } else { arguments.subList(0, arguments.size - 1) } + // If this is an overloading indexed access operator, it could have default values in the middle. + // For proper argument mapping, wrap the last one, which is supposed to be the updated value, as a named argument. + if ((function as? FirSimpleFunction)?.isOperator == true && + function.name == Name.identifier("set") && + function.valueParameters.any { it.defaultValue != null } + ) { + val v = argumentsInParenthesis.last() + if (v !is FirNamedArgumentExpression) { + val namedV = buildNamedArgumentExpression { + source = v.source + expression = v + isSpread = false + name = function.valueParameters.last().name + } + argumentsInParenthesis = argumentsInParenthesis.dropLast(1) + listOf(namedV) + } + } + val processor = FirCallArgumentsProcessor(function) processor.processArgumentsInParenthesis(argumentsInParenthesis) if (externalArgument != null) { diff --git a/compiler/testData/codegen/box/defaultArguments/convention/incWithDefaults.kt b/compiler/testData/codegen/box/defaultArguments/convention/incWithDefaults.kt index c77dd08fa4e..7c9fccd6b22 100644 --- a/compiler/testData/codegen/box/defaultArguments/convention/incWithDefaults.kt +++ b/compiler/testData/codegen/box/defaultArguments/convention/incWithDefaults.kt @@ -1,5 +1,4 @@ // !LANGUAGE: +ProperArrayConventionSetterWithDefaultCalls -// IGNORE_BACKEND_FIR: JVM_IR var inc: String = "" class X { diff --git a/compiler/testData/codegen/box/defaultArguments/convention/kt16520.kt b/compiler/testData/codegen/box/defaultArguments/convention/kt16520.kt index cb403b24030..a2f9ac23946 100644 --- a/compiler/testData/codegen/box/defaultArguments/convention/kt16520.kt +++ b/compiler/testData/codegen/box/defaultArguments/convention/kt16520.kt @@ -1,5 +1,4 @@ // !LANGUAGE: +ProperArrayConventionSetterWithDefaultCalls -// IGNORE_BACKEND_FIR: JVM_IR var result = "fail" class A { diff --git a/compiler/testData/codegen/box/defaultArguments/convention/plusAssignWithDefaults.kt b/compiler/testData/codegen/box/defaultArguments/convention/plusAssignWithDefaults.kt index 1e1e83e0c4b..a8a1d50f949 100644 --- a/compiler/testData/codegen/box/defaultArguments/convention/plusAssignWithDefaults.kt +++ b/compiler/testData/codegen/box/defaultArguments/convention/plusAssignWithDefaults.kt @@ -1,5 +1,4 @@ // !LANGUAGE: +ProperArrayConventionSetterWithDefaultCalls -// IGNORE_BACKEND_FIR: JVM_IR var inc: String = "" class X { diff --git a/compiler/testData/diagnostics/tests/checkArguments/arrayAccessSet.fir.kt b/compiler/testData/diagnostics/tests/checkArguments/arrayAccessSet.fir.kt index 44253d12008..08857777990 100644 --- a/compiler/testData/diagnostics/tests/checkArguments/arrayAccessSet.fir.kt +++ b/compiler/testData/diagnostics/tests/checkArguments/arrayAccessSet.fir.kt @@ -21,12 +21,12 @@ object Z { } fun test() { - A[0] = "" - A[0] = 2.72 + A[0] = "" + A[0] = 2.72 - B[0] = "" - B[0] = 2.72 - B[0] = true + B[0] = "" + B[0] = 2.72 + B[0] = true D[0] = "" D[0] = 2.72 diff --git a/compiler/testData/diagnostics/tests/regressions/kt10633.fir.kt b/compiler/testData/diagnostics/tests/regressions/kt10633.fir.kt index 0b14f8f5049..050c5191274 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt10633.fir.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt10633.fir.kt @@ -11,9 +11,9 @@ operator fun Int.set(s: Int, x: String = "", z: Int) { } fun main() { - 1[2] = 1 + 1[2] = 1 1.set(2, z = 1) 1[2] += 1 - 1.set(2, 1) + 1.set(2, 1) } diff --git a/compiler/testData/ir/irText/expressions/kt28456b.fir.txt b/compiler/testData/ir/irText/expressions/kt28456b.fir.txt index 31d2764642e..d226c14deb0 100644 --- a/compiler/testData/ir/irText/expressions/kt28456b.fir.txt +++ b/compiler/testData/ir/irText/expressions/kt28456b.fir.txt @@ -47,9 +47,10 @@ FILE fqName: fileName:/kt28456b.kt FUN name:testSimpleAssignment visibility:public modality:FINAL <> (a:.A) returnType:kotlin.Unit VALUE_PARAMETER name:a index:0 type:.A BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit - CONST Int type=kotlin.Int value=1 - CONST Int type=kotlin.Int value=0 + CALL 'public final fun set (i: kotlin.Int, j: kotlin.Int, v: kotlin.Int): kotlin.Unit [operator] declared in ' type=kotlin.Unit origin=null + $receiver: GET_VAR 'a: .A declared in .testSimpleAssignment' type=.A origin=null + i: CONST Int type=kotlin.Int value=1 + v: CONST Int type=kotlin.Int value=0 FUN name:testPostfixIncrement visibility:public modality:FINAL <> (a:.A) returnType:kotlin.Int VALUE_PARAMETER name:a index:0 type:.A BLOCK_BODY @@ -59,9 +60,10 @@ FILE fqName: fileName:/kt28456b.kt CALL 'public final fun get (i: kotlin.Int, a: kotlin.Int, b: kotlin.Int, c: kotlin.Int, d: kotlin.Int): kotlin.Int [operator] declared in ' type=kotlin.Int origin=null $receiver: GET_VAR 'a: .A declared in .testPostfixIncrement' type=.A origin=null i: CONST Int type=kotlin.Int value=1 - ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit - CONST Int type=kotlin.Int value=1 - CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + CALL 'public final fun set (i: kotlin.Int, j: kotlin.Int, v: kotlin.Int): kotlin.Unit [operator] declared in ' type=kotlin.Unit origin=null + $receiver: GET_VAR 'a: .A declared in .testPostfixIncrement' type=.A origin=null + i: CONST Int type=kotlin.Int value=1 + v: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null $this: GET_VAR 'val tmp_0: kotlin.Int [val] declared in .testPostfixIncrement' type=kotlin.Int origin=null GET_VAR 'val tmp_0: kotlin.Int [val] declared in .testPostfixIncrement' type=kotlin.Int origin=null FUN name:testCompoundAssignment visibility:public modality:FINAL <> (a:.A) returnType:kotlin.Unit @@ -72,9 +74,10 @@ FILE fqName: fileName:/kt28456b.kt GET_VAR 'a: .A declared in .testCompoundAssignment' type=.A origin=null VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.Int [val] CONST Int type=kotlin.Int value=1 - ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit - GET_VAR 'val tmp_2: kotlin.Int [val] declared in .testCompoundAssignment' type=kotlin.Int origin=null - CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + CALL 'public final fun set (i: kotlin.Int, j: kotlin.Int, v: kotlin.Int): kotlin.Unit [operator] declared in ' type=kotlin.Unit origin=null + $receiver: GET_VAR 'val tmp_1: .A [val] declared in .testCompoundAssignment' type=.A origin=null + i: GET_VAR 'val tmp_2: kotlin.Int [val] declared in .testCompoundAssignment' type=kotlin.Int origin=null + v: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null $this: CALL 'public final fun get (i: kotlin.Int, a: kotlin.Int, b: kotlin.Int, c: kotlin.Int, d: kotlin.Int): kotlin.Int [operator] declared in ' type=kotlin.Int origin=null $receiver: GET_VAR 'val tmp_1: .A [val] declared in .testCompoundAssignment' type=.A origin=null i: GET_VAR 'val tmp_2: kotlin.Int [val] declared in .testCompoundAssignment' type=kotlin.Int origin=null