diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java index 044aa9e1f4f..d9403b67808 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java @@ -921,6 +921,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis runTest("compiler/fir/analysis-tests/testData/resolve/arguments/overloadWithDefault.kt"); } + @Test + @TestMetadata("setWithTrailingLambda.kt") + public void testSetWithTrailingLambda() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/arguments/setWithTrailingLambda.kt"); + } + @Test @TestMetadata("simple.kt") public void testSimple() throws Exception { @@ -957,6 +963,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis runTest("compiler/fir/analysis-tests/testData/resolve/arguments/vararg.kt"); } + @Test + @TestMetadata("varargFromJava.kt") + public void testVarargFromJava() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/arguments/varargFromJava.kt"); + } + @Test @TestMetadata("varargOfLambdasWithReceiver.kt") public void testVarargOfLambdasWithReceiver() throws Exception { diff --git a/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java b/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java index c64365e3efe..2e14b330d35 100644 --- a/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java +++ b/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java @@ -784,6 +784,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract runTest("compiler/fir/analysis-tests/testData/resolve/arguments/overloadWithDefault.kt"); } + @TestMetadata("setWithTrailingLambda.kt") + public void testSetWithTrailingLambda() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/arguments/setWithTrailingLambda.kt"); + } + @TestMetadata("simple.kt") public void testSimple() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/arguments/simple.kt"); @@ -814,6 +819,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract runTest("compiler/fir/analysis-tests/testData/resolve/arguments/vararg.kt"); } + @TestMetadata("varargFromJava.kt") + public void testVarargFromJava() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/arguments/varargFromJava.kt"); + } + @TestMetadata("varargOfLambdasWithReceiver.kt") public void testVarargOfLambdasWithReceiver() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/arguments/varargOfLambdasWithReceiver.kt"); diff --git a/compiler/fir/analysis-tests/testData/resolve/arguments/setWithTrailingLambda.fir.txt b/compiler/fir/analysis-tests/testData/resolve/arguments/setWithTrailingLambda.fir.txt new file mode 100644 index 00000000000..59b2b72ff83 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/arguments/setWithTrailingLambda.fir.txt @@ -0,0 +1,38 @@ +FILE: setWithTrailingLambda.kt + public final fun test(m: R|MyMap|): R|kotlin/Unit| { + R|/m|.R|SubstitutionOverride| kotlin/Unit|>(Q|SomeKey|, = set@fun (: R|kotlin/String|, : R|@R|kotlin/ParameterName|(name = String(bar)) kotlin/Any|): R|kotlin/Unit| { + ^@set Unit + } + ) + R|/m|.R|SubstitutionOverride| kotlin/Unit|>(Q|SomeKey|, fun (: R|kotlin/String|, : R|@R|kotlin/ParameterName|(name = String(bar)) kotlin/Any|): R|kotlin/Unit| { + ^ Unit + } + ) + } + public final data class EditorData : R|kotlin/Any| { + public constructor(meta: R|MyMap|): R|EditorData| { + super() + } + + public final val meta: R|MyMap| = R|/meta| + public get(): R|MyMap| + + public final operator fun component1(): R|MyMap| + + public final fun copy(meta: R|MyMap| = this@R|/EditorData|.R|/EditorData.meta|): R|EditorData| + + } + public abstract interface MyMap : R|kotlin/Any| { + public abstract operator fun set(k: R|Key|, v: R|T|): R|kotlin/Unit| + + } + public abstract interface Key : R|kotlin/Any| { + } + public abstract interface EditorDataKey : R|Key| { + } + public final object SomeKey : R|EditorDataKey>| { + private constructor(): R|SomeKey| { + super() + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/arguments/setWithTrailingLambda.kt b/compiler/fir/analysis-tests/testData/resolve/arguments/setWithTrailingLambda.kt new file mode 100644 index 00000000000..223731f4619 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/arguments/setWithTrailingLambda.kt @@ -0,0 +1,18 @@ +// ISSUE: KT-56714 + +fun test(m: MyMap) { + m.set(SomeKey) { _, _ -> } + m[SomeKey] = { _, _ -> } +} + +data class EditorData(val meta: MyMap) + +interface MyMap { + operator fun set(k: Key, v: T) +} + +interface Key + +interface EditorDataKey : Key + +object SomeKey : EditorDataKey<(String, bar: Any) -> Unit> diff --git a/compiler/fir/analysis-tests/testData/resolve/arguments/varargFromJava.fir.txt b/compiler/fir/analysis-tests/testData/resolve/arguments/varargFromJava.fir.txt new file mode 100644 index 00000000000..d345fb775b3 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/arguments/varargFromJava.fir.txt @@ -0,0 +1,11 @@ +FILE: main.kt + public final class Some : R|kotlin/Any| { + public constructor(): R|Some| { + super() + } + + public final fun test(handle: R|VarHandle|): R|kotlin/Unit| { + R|/handle|.R|/VarHandle.set|(vararg(this@R|/Some|, Boolean(false))) + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/arguments/varargFromJava.kt b/compiler/fir/analysis-tests/testData/resolve/arguments/varargFromJava.kt new file mode 100644 index 00000000000..eede6330349 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/arguments/varargFromJava.kt @@ -0,0 +1,11 @@ +// FILE: VarHandle.java +public class VarHandle { + public void set(Object... args) {} +} + +// FILE: main.kt +class Some { + fun test(handle: VarHandle) { + handle.set(this, false) + } +} diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeDiagnosticsTestGenerated.java index 2af3282deeb..91619d30583 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeDiagnosticsTestGenerated.java @@ -921,6 +921,12 @@ public class FirLightTreeDiagnosticsTestGenerated extends AbstractFirLightTreeDi runTest("compiler/fir/analysis-tests/testData/resolve/arguments/overloadWithDefault.kt"); } + @Test + @TestMetadata("setWithTrailingLambda.kt") + public void testSetWithTrailingLambda() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/arguments/setWithTrailingLambda.kt"); + } + @Test @TestMetadata("simple.kt") public void testSimple() throws Exception { @@ -957,6 +963,12 @@ public class FirLightTreeDiagnosticsTestGenerated extends AbstractFirLightTreeDi runTest("compiler/fir/analysis-tests/testData/resolve/arguments/vararg.kt"); } + @Test + @TestMetadata("varargFromJava.kt") + public void testVarargFromJava() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/arguments/varargFromJava.kt"); + } + @Test @TestMetadata("varargOfLambdasWithReceiver.kt") public void testVarargOfLambdasWithReceiver() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiDiagnosticTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiDiagnosticTestGenerated.java index 9cf6eed532a..049ba02f714 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiDiagnosticTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiDiagnosticTestGenerated.java @@ -921,6 +921,12 @@ public class FirPsiDiagnosticTestGenerated extends AbstractFirPsiDiagnosticTest runTest("compiler/fir/analysis-tests/testData/resolve/arguments/overloadWithDefault.kt"); } + @Test + @TestMetadata("setWithTrailingLambda.kt") + public void testSetWithTrailingLambda() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/arguments/setWithTrailingLambda.kt"); + } + @Test @TestMetadata("simple.kt") public void testSimple() throws Exception { @@ -957,6 +963,12 @@ public class FirPsiDiagnosticTestGenerated extends AbstractFirPsiDiagnosticTest runTest("compiler/fir/analysis-tests/testData/resolve/arguments/vararg.kt"); } + @Test + @TestMetadata("varargFromJava.kt") + public void testVarargFromJava() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/arguments/varargFromJava.kt"); + } + @Test @TestMetadata("varargOfLambdasWithReceiver.kt") public void testVarargOfLambdasWithReceiver() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallableReferenceResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallableReferenceResolution.kt index 5f148908380..178fb2d6dad 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallableReferenceResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallableReferenceResolution.kt @@ -174,7 +174,7 @@ private fun BodyResolveComponents.getCallableReferenceAdaptation( val fakeArguments = createFakeArgumentsForReference(function, expectedArgumentsCount, inputTypes, unboundReceiverCount) // TODO: Use correct originScope - val argumentMapping = mapArguments(fakeArguments, function, originScope = null) + val argumentMapping = mapArguments(fakeArguments, function, originScope = null, callSiteIsOperatorCall = false) if (argumentMapping.diagnostics.any { !it.applicability.isSuccess }) return null /** 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 df0cc066c9d..4de2a1285cd 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 @@ -13,7 +13,6 @@ import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.declarations.utils.isOperator import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.builder.buildNamedArgumentExpression -import org.jetbrains.kotlin.fir.isIntersectionOverride import org.jetbrains.kotlin.fir.isSubstitutionOrIntersectionOverride import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents import org.jetbrains.kotlin.fir.resolve.defaultParameterResolver @@ -65,6 +64,7 @@ fun BodyResolveComponents.mapArguments( arguments: List, function: FirFunction, originScope: FirScope?, + callSiteIsOperatorCall: Boolean ): ArgumentMapping { if (arguments.isEmpty() && function.valueParameters.isEmpty()) { return EmptyArgumentMapping @@ -87,7 +87,8 @@ fun BodyResolveComponents.mapArguments( // If this is an indexed access set operator, it could have default values or a vararg parameter in the middle. // For proper argument mapping, wrap the last one, which is supposed to be the updated value, as a named argument. - val isIndexedSetOperator = function is FirSimpleFunction + val isIndexedSetOperator = callSiteIsOperatorCall + && function is FirSimpleFunction && function.isOperator && function.name == OperatorNameConventions.SET && function.origin !is FirDeclarationOrigin.DynamicScope diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt index c2602fbf5c4..abfff0632b5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt @@ -424,8 +424,12 @@ internal object MapArguments : ResolutionStage() { override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) { val symbol = candidate.symbol as? FirFunctionSymbol<*> ?: return sink.reportDiagnostic(HiddenCandidate) val function = symbol.fir - - val mapping = context.bodyResolveComponents.mapArguments(callInfo.arguments, function, candidate.originScope) + val mapping = context.bodyResolveComponents.mapArguments( + callInfo.arguments, + function, + candidate.originScope, + callSiteIsOperatorCall = (callInfo.callSite as? FirFunctionCall)?.origin == FirFunctionCallOrigin.Operator + ) candidate.argumentMapping = mapping.toArgumentToParameterMapping() candidate.numDefaults = mapping.numDefaults() diff --git a/compiler/testData/diagnostics/tests/regressions/kt10633.fir.kt b/compiler/testData/diagnostics/tests/regressions/kt10633.fir.kt index 050c5191274..76d3a221907 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt10633.fir.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt10633.fir.kt @@ -15,5 +15,5 @@ fun main() { 1.set(2, z = 1) 1[2] += 1 - 1.set(2, 1) + 1.set(2, 1) }