From e696d1d06ae40734043ff5e3e3146cc31641282a Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Fri, 14 Feb 2020 11:10:46 +0300 Subject: [PATCH] [FIR] Improve mapping arguments to parameters --- .../kotlin/fir/resolve/calls/Arguments.kt | 19 +- .../kotlin/fir/resolve/calls/Candidate.kt | 2 + .../calls/FirArgumentsToParametersMapper.kt | 257 ++++++++++++++++++ .../calls/FirCallArgumentsProcessor.kt | 119 -------- .../fir/resolve/calls/ResolutionDiagnostic.kt | 51 ++++ .../fir/resolve/calls/ResolvedCallArgument.kt | 26 ++ .../kotlin/fir/resolve/calls/ResolverParts.kt | 26 +- .../testData/resolve/arguments/lambda.kt | 6 + .../testData/resolve/arguments/simple.kt | 2 +- .../testData/resolve/arguments/simple.txt | 4 +- .../testData/resolve/arguments/vararg.txt | 2 +- .../box/mixedNamedPosition/defaults.kt | 1 - .../codegen/box/mixedNamedPosition/simple.kt | 1 - .../testData/codegen/box/vararg/kt6192.kt | 1 - .../singleAssignmentToVarargsInFunction.kt | 1 + .../testData/diagnostics/tests/Varargs.fir.kt | 4 +- .../tests/checkArguments/SpreadVarargs.fir.kt | 50 ++-- .../checkArguments/twoLambdasFunction.fir.kt | 2 +- .../spreadOperator_after.fir.kt | 4 +- .../spreadOperator_before.fir.kt | 4 +- .../mixedNamedPosition/defaults.fir.kt | 6 +- .../mixedNamedPosition/disabledFeature.fir.kt | 6 +- .../mixedNamedPosition/oldInference.fir.kt | 6 +- .../mixedNamedPosition/simple.fir.kt | 6 +- .../mixedNamedPosition/varargs.fir.kt | 14 +- .../tests/resolve/newLineLambda.fir.kt | 2 +- .../varargsInDifferentPositions.fir.kt | 2 +- .../overloadConflicts/varargsMixed.fir.kt | 4 +- .../varargsInDelegationCallToPrimary.fir.kt | 2 +- .../varargsInDelegationCallToSecondary.fir.kt | 2 +- ...assignArrayToVararagInNamedForm_1_3.fir.kt | 4 +- ...assignArrayToVararagInNamedForm_1_4.fir.kt | 4 +- ...entsInNamedFormFunDeprecation_after.fir.kt | 30 +- ...ntsInNamedFormFunDeprecation_before.fir.kt | 30 +- .../noAssigningArraysToVarargsFeature.fir.kt | 2 +- ...tAssigningSingleElementsInNamedForm.fir.kt | 2 +- .../ir/irText/expressions/vararg.fir.txt | 22 +- .../org/jetbrains/kotlin/utils/addToStdlib.kt | 3 + .../references/invoke/lambdaAndParens.kt | 2 + .../resolve/references/invoke/lambdaNoPar.kt | 2 + .../references/invoke/lambdaNoParLabel.kt | 2 + .../references/invoke/lambdaNoParRCurly.kt | 2 + .../references/invoke/nonemptyLambdaRPar.kt | 2 + 43 files changed, 498 insertions(+), 241 deletions(-) create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirArgumentsToParametersMapper.kt delete mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirCallArgumentsProcessor.kt create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolvedCallArgument.kt diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt index 067a27a498a..7ad59cc2252 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt @@ -324,16 +324,19 @@ private fun Candidate.getExpectedTypeWithSAMConversion( internal fun FirExpression.getExpectedType( session: FirSession, parameter: FirValueParameter/*, languageVersionSettings: LanguageVersionSettings*/ -) = -// if (this.isSpread || this.isArrayAssignedAsNamedArgumentInAnnotation(parameter, languageVersionSettings)) { -// parameter.type.unwrap() -// } else { - if (parameter.isVararg && (this !is FirWrappedArgumentExpression || !isSpread)) { +): ConeKotlinType { + val shouldUnwrapVarargType = when (this) { + is FirSpreadArgumentExpression -> !isSpread + is FirNamedArgumentExpression -> false + else -> true + } + + return if (parameter.isVararg && shouldUnwrapVarargType) { parameter.returnTypeRef.coneTypeUnsafe().varargElementType(session) } else { parameter.returnTypeRef.coneTypeUnsafe() - }//?.varargElementType?.unwrap() ?: parameter.type.unwrap() -// } + } +} private fun ConeKotlinType.varargElementType(session: FirSession): ConeKotlinType { @@ -354,4 +357,4 @@ fun FirTypeRef.isExtensionFunctionType(session: FirSession): Boolean { if (typeAlias.expandedTypeRef.annotations.any(FirAnnotationCall::isExtensionFunctionAnnotationCall)) return true return false -} +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt index 40590695b37..fbf4c7396ad 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt @@ -109,6 +109,8 @@ class Candidate( var argumentMapping: Map? = null val postponedAtoms = mutableListOf() + val diagnostics: MutableList = mutableListOf() + fun dispatchReceiverExpression(): FirExpression = when (explicitReceiverKind) { ExplicitReceiverKind.DISPATCH_RECEIVER, ExplicitReceiverKind.BOTH_RECEIVERS -> callInfo.explicitReceiver!! else -> dispatchReceiverValue?.receiverExpression ?: FirNoReceiverExpression 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 new file mode 100644 index 00000000000..4a17982c036 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirArgumentsToParametersMapper.kt @@ -0,0 +1,257 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.resolve.calls + +import org.jetbrains.kotlin.fir.declarations.FirFunction +import org.jetbrains.kotlin.fir.declarations.FirValueParameter +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.name.Name +import java.util.* +import kotlin.collections.ArrayList +import kotlin.collections.component1 +import kotlin.collections.component2 +import kotlin.collections.set + + +data class ArgumentMapping( + // This map should be ordered by arguments as written, e.g.: + // fun foo(a: Int, b: Int) {} + // foo(b = bar(), a = qux()) + // parameterToCallArgumentMap.values() should be [ 'bar()', 'foo()' ] + val parameterToCallArgumentMap: Map, + val diagnostics: List +) + +private val EmptyArgumentMapping = ArgumentMapping(emptyMap(), emptyList()) + +fun mapArguments( + arguments: List, + function: FirFunction<*> +): ArgumentMapping { + if (arguments.isEmpty() && function.valueParameters.isEmpty()) { + return EmptyArgumentMapping + } + val externalArgument: FirExpression? = arguments.lastOrNull { it is FirLambdaArgumentExpression } + val argumentsInParenthesis: List = if (externalArgument == null) { + arguments + } else { + arguments.subList(0, arguments.size - 1) + } + + val processor = FirCallArgumentsProcessor(function) + processor.processArgumentsInParenthesis(argumentsInParenthesis) + if (externalArgument != null) { + processor.processExternalArgument(externalArgument) + } + processor.processDefaultsAndRunChecks() + + return ArgumentMapping(processor.result, processor.diagnostics ?: emptyList()) +} + +private class FirCallArgumentsProcessor(private val function: FirFunction<*>) { + private var state = State.POSITION_ARGUMENTS + private var currentPositionedParameterIndex = 0 + private var varargArguments: MutableList? = null + private var nameToParameter: Map? = null + var diagnostics: MutableList? = null + private set + val result: MutableMap = LinkedHashMap() + + private enum class State { + POSITION_ARGUMENTS, + VARARG_POSITION, + NAMED_ONLY_ARGUMENTS + } + + fun processArgumentsInParenthesis(arguments: List) { + for (argument in arguments) { + val argumentName = argument.argumentName + + // process position argument + if (argumentName == null) { + if (processPositionArgument(argument)) { + state = State.VARARG_POSITION + } + } + // process named argument + else { + if (state == State.VARARG_POSITION) { + completeVarargPositionArguments() + } + state = State.NAMED_ONLY_ARGUMENTS + + processNamedArgument(argument, argumentName) + } + } + if (state == State.VARARG_POSITION) { + completeVarargPositionArguments() + } + } + + // return true, if it was mapped to vararg parameter + private fun processPositionArgument(argument: FirExpression): Boolean { + if (state == State.NAMED_ONLY_ARGUMENTS) { + addDiagnostic(MixingNamedAndPositionArguments(argument)) + return false + } + + val parameter = parameters.getOrNull(currentPositionedParameterIndex) + if (parameter == null) { + addDiagnostic(TooManyArguments(argument, function)) + return false + } + + if (!parameter.isVararg) { + currentPositionedParameterIndex++ + + result[parameter] = ResolvedCallArgument.SimpleArgument(argument) + return false + } + // all position arguments will be mapped to current vararg parameter + else { + addVarargArgument(argument) + return true + } + } + + private fun processNamedArgument(argument: FirExpression, name: Name) { + if (!function.hasStableParameterNames) { + addDiagnostic(NamedArgumentNotAllowed(argument, function)) + } + + val parameter = findParameterByName(argument, name) ?: return + + result[parameter]?.let { + addDiagnostic(ArgumentPassedTwice(argument, parameter, it)) + return + } + + result[parameter] = ResolvedCallArgument.SimpleArgument(argument) + + if (parameters.getOrNull(currentPositionedParameterIndex) == parameter) { + state = State.POSITION_ARGUMENTS + currentPositionedParameterIndex++ + } + } + + fun processExternalArgument(externalArgument: FirExpression) { + val lastParameter = parameters.lastOrNull() + if (lastParameter == null) { + addDiagnostic(TooManyArguments(externalArgument, function)) + return + } + + if (lastParameter.isVararg) { + addDiagnostic(VarargArgumentOutsideParentheses(externalArgument, lastParameter)) + return + } + + val previousOccurrence = result[lastParameter] + if (previousOccurrence != null) { + addDiagnostic(TooManyArguments(externalArgument, function)) + return + } + + + result[lastParameter] = ResolvedCallArgument.SimpleArgument(externalArgument) + } + + fun processDefaultsAndRunChecks() { + for ((parameter, resolvedArgument) in result) { + if (!parameter.isVararg) { + if (resolvedArgument !is ResolvedCallArgument.SimpleArgument) { + error("Incorrect resolved argument for parameter $parameter :$resolvedArgument") + } else if (resolvedArgument.callArgument.isSpread) { + addDiagnostic(NonVarargSpread(resolvedArgument.callArgument)) + } + } + } + + for (parameter in parameters) { + if (!result.containsKey(parameter)) { + if (parameter.defaultValue != null) { + result[parameter] = ResolvedCallArgument.DefaultArgument + } else if (parameter.isVararg) { + result[parameter] = ResolvedCallArgument.VarargArgument(emptyList()) + } else { + addDiagnostic(NoValueForParameter(parameter, function)) + } + } + } + } + + + private fun completeVarargPositionArguments() { + assert(state == State.VARARG_POSITION) { "Incorrect state: $state" } + val parameter = parameters[currentPositionedParameterIndex] + result.put(parameter, ResolvedCallArgument.VarargArgument(varargArguments!!)) + } + + private fun addVarargArgument(argument: FirExpression) { + if (varargArguments == null) { + varargArguments = ArrayList() + } + varargArguments!!.add(argument) + } + + private fun getParameterByName(name: Name): FirValueParameter? { + if (nameToParameter == null) { + nameToParameter = parameters.associateBy { it.name } + } + return nameToParameter!![name] + } + + private fun findParameterByName(argument: FirExpression, name: Name): FirValueParameter? { + val parameter = getParameterByName(name) + + // TODO +// if (descriptor is CallableMemberDescriptor && descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { +// if (parameter == null) { +// for (valueParameter in descriptor.valueParameters) { +// val matchedParameter = valueParameter.overriddenDescriptors.firstOrNull { +// it.containingDeclaration.hasStableParameterNames() && it.name == name +// } +// if (matchedParameter != null) { +// addDiagnostic(NamedArgumentReference(argument, valueParameter)) +// addDiagnostic(NameForAmbiguousParameter(argument, valueParameter, matchedParameter)) +// return valueParameter +// } +// } +// } else { +// parameter.getOverriddenParameterWithOtherName()?.let { +// addDiagnostic(NameForAmbiguousParameter(argument, parameter, it)) +// } +// } +// } +// + if (parameter == null) addDiagnostic(NameNotFound(argument, function)) + + return parameter + } + + private fun addDiagnostic(diagnostic: ResolutionDiagnostic) { + if (diagnostics == null) { + diagnostics = mutableListOf() + } + diagnostics!!.add(diagnostic) + } + + private val FirExpression.isSpread: Boolean + get() = this is FirSpreadArgumentExpression && isSpread + + private val parameters: List + get() = function.valueParameters + + private val FirExpression.argumentName: Name? + get() = (this as? FirNamedArgumentExpression)?.name + + // TODO: handle java functions + private val FirFunction<*>.hasStableParameterNames: Boolean + get() = true +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirCallArgumentsProcessor.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirCallArgumentsProcessor.kt deleted file mode 100644 index 5b99e6dfa9c..00000000000 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirCallArgumentsProcessor.kt +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license - * that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.fir.resolve.calls - -import org.jetbrains.kotlin.fir.declarations.FirFunction -import org.jetbrains.kotlin.fir.declarations.FirValueParameter -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.FirWrappedArgumentExpression -import org.jetbrains.kotlin.fir.render - -class FirCallArgumentsProcessor( - private val function: FirFunction<*>, - private val arguments: List -) { - class Result(val argumentMapping: Map, val isSuccess: Boolean) - - fun process(): Result { - var currentState: State = State.PositionalOnly(function.valueParameters) - for (argument in arguments) { - if (argument is FirNamedArgumentExpression || argument is FirLambdaArgumentExpression) { - currentState = State.PositionalThenNamed( - function.valueParameters, - currentState.argumentMap, - currentState.usedParameters - ) - } - val status = currentState.processArgument(argument) - if (status != MappingStatus.SUCCESS) { - // unmapped argument - return Result(currentState.argumentMap, isSuccess = false) - } - } - - for (valueParameter in function.valueParameters) { - if (valueParameter !in currentState.usedParameters && !valueParameter.isVararg && valueParameter.defaultValue == null) { - // unmapped parameter - return Result(currentState.argumentMap, isSuccess = false) - } - } - return Result(currentState.argumentMap, isSuccess = currentState.argumentMap.size == arguments.size) - } - - private enum class MappingStatus { - SUCCESS, - ERROR - } - - private sealed class State( - val valueParameters: List, - val argumentMap: MutableMap = mutableMapOf(), - val usedParameters: MutableSet = mutableSetOf() - ) { - abstract fun processArgument(argument: FirExpression): MappingStatus - - class PositionalOnly(valueParameters: List) : State(valueParameters) { - var currentParameterIndex: Int = 0 - - val currentParameter get() = valueParameters.getOrNull(currentParameterIndex) - - override fun processArgument(argument: FirExpression): MappingStatus { - require(argument !is FirNamedArgumentExpression) { - "Positional-only argument processor state should not receive ${argument.render()}" - } - - val currentParameter = currentParameter ?: return MappingStatus.ERROR - argumentMap[argument] = currentParameter - - val isSpread = argument is FirWrappedArgumentExpression && argument.isSpread - if (!currentParameter.isVararg || isSpread) { - usedParameters += currentParameter - currentParameterIndex++ - } - - if (!currentParameter.isVararg && isSpread) { - return MappingStatus.ERROR - } - - return MappingStatus.SUCCESS - } - } - - class PositionalThenNamed( - valueParameters: List, - argumentMap: MutableMap, - usedParameters: MutableSet - ) : State(valueParameters, argumentMap, usedParameters) { - val nameToParameter = valueParameters.associateBy { it.name } - - private fun map(parameter: FirValueParameter, argument: FirExpression): MappingStatus { - if (parameter in usedParameters) return MappingStatus.ERROR - argumentMap[argument] = parameter - usedParameters += parameter - return MappingStatus.SUCCESS - } - - override fun processArgument(argument: FirExpression): MappingStatus { - when (argument) { - is FirNamedArgumentExpression -> { - val name = argument.name - val parameter = nameToParameter[name] ?: return MappingStatus.ERROR - return map(parameter, argument) - } - is FirLambdaArgumentExpression -> { - val lastParameter = valueParameters.lastOrNull() ?: return MappingStatus.ERROR - return map(lastParameter, argument) - } - else -> { - return MappingStatus.ERROR - } - } - } - } - } -} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt new file mode 100644 index 00000000000..87ace7de7b9 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.resolve.calls + +import org.jetbrains.kotlin.fir.declarations.FirFunction +import org.jetbrains.kotlin.fir.declarations.FirValueParameter +import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability + +abstract class ResolutionDiagnostic(val applicability: CandidateApplicability) + +abstract class InapplicableArgumentDiagnostic : ResolutionDiagnostic(CandidateApplicability.INAPPLICABLE) { + abstract val argument: FirExpression +} + +class MixingNamedAndPositionArguments(override val argument: FirExpression) : InapplicableArgumentDiagnostic() +class TooManyArguments( + val argument: FirExpression, + val function: FirFunction<*> +) : ResolutionDiagnostic(CandidateApplicability.PARAMETER_MAPPING_ERROR) + +class NamedArgumentNotAllowed( + override val argument: FirExpression, + val function: FirFunction<*> +) : InapplicableArgumentDiagnostic() + +class ArgumentPassedTwice( + override val argument: FirExpression, + val valueParameter: FirValueParameter, + val firstOccurrence: ResolvedCallArgument +) : InapplicableArgumentDiagnostic() + +class VarargArgumentOutsideParentheses( + override val argument: FirExpression, + val valueParameter: FirValueParameter +) : InapplicableArgumentDiagnostic() + +class NonVarargSpread(override val argument: FirExpression) : InapplicableArgumentDiagnostic() + +class NoValueForParameter( + val valueParameter: FirValueParameter, + val function: FirFunction<*> +) : ResolutionDiagnostic(CandidateApplicability.PARAMETER_MAPPING_ERROR) + +class NameNotFound( + override val argument: FirExpression, + val function: FirFunction<*> +) : InapplicableArgumentDiagnostic() \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolvedCallArgument.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolvedCallArgument.kt new file mode 100644 index 00000000000..29f483c3bd5 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolvedCallArgument.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.resolve.calls + +import org.jetbrains.kotlin.fir.expressions.FirExpression + +sealed class ResolvedCallArgument { + abstract val arguments: List + + object DefaultArgument : ResolvedCallArgument() { + override val arguments: List + get() = emptyList() + + } + + class SimpleArgument(val callArgument: FirExpression) : ResolvedCallArgument() { + override val arguments: List + get() = listOf(callArgument) + + } + + class VarargArgument(override val arguments: List) : ResolvedCallArgument() +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolverParts.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolverParts.kt index 8752702c5db..c14d5f3d161 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolverParts.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolverParts.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.* +import org.jetbrains.kotlin.utils.addToStdlib.min abstract class ResolutionStage { @@ -154,11 +155,26 @@ internal object MapArguments : ResolutionStage() { override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) { val symbol = candidate.symbol as? FirFunctionSymbol<*> ?: return sink.reportApplicability(CandidateApplicability.HIDDEN) val function = symbol.fir - val processor = FirCallArgumentsProcessor(function, callInfo.arguments) - val mappingResult = processor.process() - candidate.argumentMapping = mappingResult.argumentMapping - if (!mappingResult.isSuccess) { - return sink.yieldApplicability(CandidateApplicability.PARAMETER_MAPPING_ERROR) + + val mapping = mapArguments(callInfo.arguments, function) + val argumentToParameterMapping = mutableMapOf() + mapping.parameterToCallArgumentMap.forEach { (valueParameter, resolvedArgument) -> + when (resolvedArgument) { + is ResolvedCallArgument.SimpleArgument -> argumentToParameterMapping[resolvedArgument.callArgument] = valueParameter + is ResolvedCallArgument.VarargArgument -> resolvedArgument.arguments.forEach { + argumentToParameterMapping[it] = valueParameter + } + } + } + candidate.argumentMapping = argumentToParameterMapping + + var applicability = CandidateApplicability.RESOLVED + mapping.diagnostics.forEach { + candidate.diagnostics += it + applicability = min(applicability, it.applicability) + } + if (applicability < CandidateApplicability.RESOLVED) { + return sink.yieldApplicability(applicability) } } } diff --git a/compiler/fir/resolve/testData/resolve/arguments/lambda.kt b/compiler/fir/resolve/testData/resolve/arguments/lambda.kt index 533f0f63e27..d593651712a 100644 --- a/compiler/fir/resolve/testData/resolve/arguments/lambda.kt +++ b/compiler/fir/resolve/testData/resolve/arguments/lambda.kt @@ -4,24 +4,30 @@ fun baz(f: () -> Unit, other: Boolean = true) {} fun test() { + // OK foo {} foo() {} foo({}) + // Bad foo(1) {} foo(f = {}) {} + // OK bar(1) {} bar(x = 1) {} bar(1, {}) bar(x = 1, f = {}) + // Bad bar {} bar({}) + // OK baz(other = false, f = {}) baz({}, false) + // Bad baz {} baz() {} baz(other = false) {} diff --git a/compiler/fir/resolve/testData/resolve/arguments/simple.kt b/compiler/fir/resolve/testData/resolve/arguments/simple.kt index 45f51e84fc2..c043e7a8ca1 100644 --- a/compiler/fir/resolve/testData/resolve/arguments/simple.kt +++ b/compiler/fir/resolve/testData/resolve/arguments/simple.kt @@ -9,7 +9,7 @@ fun test() { foo() foo(0.0, false, 0, "") - foo(1, 2.0, third = true, "") + foo(1, 2.0, third = true, "") foo(second = 0.0, first = 0, fourth = "") foo(first = 0.0, second = 0, third = "", fourth = false) foo(first = 0, second = 0.0, third = false, fourth = "", first = 1) diff --git a/compiler/fir/resolve/testData/resolve/arguments/simple.txt b/compiler/fir/resolve/testData/resolve/arguments/simple.txt index 51808274162..ed1492ff5a4 100644 --- a/compiler/fir/resolve/testData/resolve/arguments/simple.txt +++ b/compiler/fir/resolve/testData/resolve/arguments/simple.txt @@ -9,9 +9,9 @@ FILE: simple.kt R|/foo|(third = Boolean(false), second = Double(2.71), fourth = String(?!), first = Int(0)) #() #(Double(0.0), Boolean(false), Int(0), String()) - #(Int(1), Double(2.0), third = Boolean(true), String()) + R|/foo|(Int(1), Double(2.0), third = Boolean(true), String()) #(second = Double(0.0), first = Int(0), fourth = String()) #(first = Double(0.0), second = Int(0), third = String(), fourth = Boolean(false)) - #(first = Int(0), second = Double(0.0), third = Boolean(false), fourth = String(), first = Int(1)) + #(first = Int(0), second = Double(0.0), third = Boolean(false), fourth = String(), first = Int(1)) #(Int(0), Double(0.0), Boolean(false), foth = String()) } diff --git a/compiler/fir/resolve/testData/resolve/arguments/vararg.txt b/compiler/fir/resolve/testData/resolve/arguments/vararg.txt index 565e04c072e..693c918a172 100644 --- a/compiler/fir/resolve/testData/resolve/arguments/vararg.txt +++ b/compiler/fir/resolve/testData/resolve/arguments/vararg.txt @@ -11,6 +11,6 @@ FILE: vararg.kt #(String()) #(Int(1), Int(2)) R|/bar|(Int(1), z = Boolean(true), vararg(y = *R|kotlin/arrayOf|(vararg(String(my), String(yours))))) - #(Int(0), z = Boolean(false), y = String(), y = String(other)) + #(Int(0), z = Boolean(false), y = String(), y = String(other)) #(Int(0), String(), Boolean(true)) } diff --git a/compiler/testData/codegen/box/mixedNamedPosition/defaults.kt b/compiler/testData/codegen/box/mixedNamedPosition/defaults.kt index 9a1f1e88197..2e9f155f135 100644 --- a/compiler/testData/codegen/box/mixedNamedPosition/defaults.kt +++ b/compiler/testData/codegen/box/mixedNamedPosition/defaults.kt @@ -1,5 +1,4 @@ // !LANGUAGE: +NewInference +MixedNamedArgumentsInTheirOwnPosition -// IGNORE_BACKEND_FIR: JVM_IR fun foo( p1: Int = 1, diff --git a/compiler/testData/codegen/box/mixedNamedPosition/simple.kt b/compiler/testData/codegen/box/mixedNamedPosition/simple.kt index e154f1ce50d..d036eb4c1cc 100644 --- a/compiler/testData/codegen/box/mixedNamedPosition/simple.kt +++ b/compiler/testData/codegen/box/mixedNamedPosition/simple.kt @@ -1,5 +1,4 @@ // !LANGUAGE: +NewInference +MixedNamedArgumentsInTheirOwnPosition -// IGNORE_BACKEND_FIR: JVM_IR fun foo( p1: Int, diff --git a/compiler/testData/codegen/box/vararg/kt6192.kt b/compiler/testData/codegen/box/vararg/kt6192.kt index 8596cc1d06e..d442cda5937 100644 --- a/compiler/testData/codegen/box/vararg/kt6192.kt +++ b/compiler/testData/codegen/box/vararg/kt6192.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR fun barB(vararg args: Byte) = args fun barC(vararg args: Char) = args fun barD(vararg args: Double) = args diff --git a/compiler/testData/codegen/box/vararg/singleAssignmentToVarargsInFunction.kt b/compiler/testData/codegen/box/vararg/singleAssignmentToVarargsInFunction.kt index b41ddc0c46d..0ebfa09e668 100644 --- a/compiler/testData/codegen/box/vararg/singleAssignmentToVarargsInFunction.kt +++ b/compiler/testData/codegen/box/vararg/singleAssignmentToVarargsInFunction.kt @@ -1,4 +1,5 @@ // !LANGUAGE: -ProhibitAssigningSingleElementsToVarargsInNamedForm +// IGNORE_BACKEND_FIR: JVM_IR fun box(): String { if (test1(p = 1) != "1") return "fail 1" diff --git a/compiler/testData/diagnostics/tests/Varargs.fir.kt b/compiler/testData/diagnostics/tests/Varargs.fir.kt index a37f503f461..eaf84907d22 100644 --- a/compiler/testData/diagnostics/tests/Varargs.fir.kt +++ b/compiler/testData/diagnostics/tests/Varargs.fir.kt @@ -12,6 +12,6 @@ fun test() { v1({}, {}) v1({}, 1, {}) v1({}, {}, {it}) - v1({}) {} - v1 {} + v1({}) {} + v1 {} } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/checkArguments/SpreadVarargs.fir.kt b/compiler/testData/diagnostics/tests/checkArguments/SpreadVarargs.fir.kt index 62252ee2c50..e40440c30dd 100644 --- a/compiler/testData/diagnostics/tests/checkArguments/SpreadVarargs.fir.kt +++ b/compiler/testData/diagnostics/tests/checkArguments/SpreadVarargs.fir.kt @@ -12,47 +12,47 @@ fun main() { join(1, "2", "3") join(*1, "2") join(1, *"2") - join(x = 1, a = "2") + join(x = 1, a = "2") join(x = *1, a = *"2") - join(x = 1, a = a) + join(x = 1, a = a) join(x = 1, a = b) join(1, *a) join(1, *b) - join(1, *a, "3") + join(1, *a, "3") join(1, *b, "3") - join(1, "4", *a, "3") + join(1, "4", *a, "3") join(1, "4", *b, "3") join(1, "4", *a) - join(1, "4", *a, *a, "3") + join(1, "4", *a, *a, "3") join(1, "4", *a, *b, "3") - join(a = a, x = 1) + join(a = a, x = 1) join(a = b, x = 1) - join(a = a, x = 1) + join(a = a, x = 1) joinG(1, "2") joinG(*1, "2") joinG(1, *"2") - joinG(x = 1, a = a) - joinG(x = 1, a = "2") + joinG(x = 1, a = a) + joinG(x = 1, a = "2") joinG(x = *1, a = *"2") joinG(1, *a) - joinG(1, *a, "3") - joinG(1, "4", *a, "3") + joinG(1, *a, "3") + joinG(1, "4", *a, "3") joinG(1, "4", *a) - joinG(1, "4", *a, *a, "3") - joinG(a = a, x = 1) + joinG(1, "4", *a, *a, "3") + joinG(a = a, x = 1) joinG(1, "2") joinG(*1, "2") joinG(1, *"2") joinG(x = 1, a = a) - joinG(x = 1, a = "2") + joinG(x = 1, a = "2") joinG(x = *1, a = *"2") joinG(1, *a) - joinG(1, *a, "3") - joinG(1, "4", *a, "3") + joinG(1, *a, "3") + joinG(1, "4", *a, "3") joinG(1, "4", *a) - joinG(1, "4", *a, *a, "3") + joinG(1, "4", *a, *a, "3") joinG(a = a, x = 1) val x1 = joinT(1, "2") @@ -61,18 +61,18 @@ fun main() { checkSubtype(x2) val x6 = joinT(1, *a) checkSubtype(x6) - val x7 = joinT(1, *a, "3") - checkSubtype(x7) - val x8 = joinT(1, "4", *a, "3") - checkSubtype(x8) + val x7 = joinT(1, *a, "3") + checkSubtype(x7) + val x8 = joinT(1, "4", *a, "3") + checkSubtype(x8) val x9 = joinT(1, "4", *a) checkSubtype(x9) - val x10 = joinT(1, "4", *a, *a, "3") - checkSubtype(x10) + val x10 = joinT(1, "4", *a, *a, "3") + checkSubtype(x10) val x11 = joinT(a = a, x = 1) - checkSubtype(x11) + checkSubtype(x11) val x12 = joinT(x = 1, a = a) - checkSubtype(x12) + checkSubtype(x12) } fun join(x : Int, vararg a : String) : String { diff --git a/compiler/testData/diagnostics/tests/checkArguments/twoLambdasFunction.fir.kt b/compiler/testData/diagnostics/tests/checkArguments/twoLambdasFunction.fir.kt index 5e5310f50e3..c1957d10528 100644 --- a/compiler/testData/diagnostics/tests/checkArguments/twoLambdasFunction.fir.kt +++ b/compiler/testData/diagnostics/tests/checkArguments/twoLambdasFunction.fir.kt @@ -6,7 +6,7 @@ fun test(x: () -> Unit, y: () -> Unit) { } fun main() { - test { + test { 1 } { 2 diff --git a/compiler/testData/diagnostics/tests/j+k/polymorphicSignature/spreadOperator_after.fir.kt b/compiler/testData/diagnostics/tests/j+k/polymorphicSignature/spreadOperator_after.fir.kt index 80247f68c1e..f39d060eb3b 100644 --- a/compiler/testData/diagnostics/tests/j+k/polymorphicSignature/spreadOperator_after.fir.kt +++ b/compiler/testData/diagnostics/tests/j+k/polymorphicSignature/spreadOperator_after.fir.kt @@ -5,7 +5,7 @@ import java.lang.invoke.MethodHandle fun test(mh: MethodHandle) { mh.invokeExact("1", "2") - mh.invokeExact(*emptyArray(), "X") - mh.invokeExact(*arrayOf("A", "B"), "C", *arrayOf("D", "E")) + mh.invokeExact(*emptyArray(), "X") + mh.invokeExact(*arrayOf("A", "B"), "C", *arrayOf("D", "E")) mh.invoke(*arrayOf("A")) } diff --git a/compiler/testData/diagnostics/tests/j+k/polymorphicSignature/spreadOperator_before.fir.kt b/compiler/testData/diagnostics/tests/j+k/polymorphicSignature/spreadOperator_before.fir.kt index e36edee5e00..ecd5ebbe4d6 100644 --- a/compiler/testData/diagnostics/tests/j+k/polymorphicSignature/spreadOperator_before.fir.kt +++ b/compiler/testData/diagnostics/tests/j+k/polymorphicSignature/spreadOperator_before.fir.kt @@ -5,7 +5,7 @@ import java.lang.invoke.MethodHandle fun test(mh: MethodHandle) { mh.invokeExact("1", "2") - mh.invokeExact(*emptyArray(), "X") - mh.invokeExact(*arrayOf("A", "B"), "C", *arrayOf("D", "E")) + mh.invokeExact(*emptyArray(), "X") + mh.invokeExact(*arrayOf("A", "B"), "C", *arrayOf("D", "E")) mh.invoke(*arrayOf("A")) } diff --git a/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/defaults.fir.kt b/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/defaults.fir.kt index 638026dae9e..5c161f2ac92 100644 --- a/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/defaults.fir.kt +++ b/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/defaults.fir.kt @@ -10,14 +10,14 @@ fun foo( ) {} fun main() { - foo(p1 = 1, "2", 3.0) - foo(1, p2 = "2", 3.0) + foo(p1 = 1, "2", 3.0) + foo(1, p2 = "2", 3.0) foo(1, "2", p3 = 3.0) foo(p1 = 1) foo(1, p2 = "2") - foo(p1 = 1, p2 = "2", 3.0) + foo(p1 = 1, p2 = "2", 3.0) foo() foo(1, p2 = "") diff --git a/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/disabledFeature.fir.kt b/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/disabledFeature.fir.kt index 63d48fa62a9..8c24c4ead05 100644 --- a/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/disabledFeature.fir.kt +++ b/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/disabledFeature.fir.kt @@ -9,11 +9,11 @@ fun foo( ) {} fun main() { - foo(p1 = 1, "2", 3.0) - foo(1, p2 = "2", 3.0) + foo(p1 = 1, "2", 3.0) + foo(1, p2 = "2", 3.0) foo(1, "2", p3 = 3.0) - foo(p1 = 1, p2 = "2", 3.0) + foo(p1 = 1, p2 = "2", 3.0) foo(1, p3 = 2.0, "") foo(1, p3 = 2.0, 3.0) diff --git a/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/oldInference.fir.kt b/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/oldInference.fir.kt index 080d5086720..e89f7f5e9a5 100644 --- a/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/oldInference.fir.kt +++ b/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/oldInference.fir.kt @@ -9,11 +9,11 @@ fun foo( ) {} fun main() { - foo(p1 = 1, "2", 3.0) - foo(1, p2 = "2", 3.0) + foo(p1 = 1, "2", 3.0) + foo(1, p2 = "2", 3.0) foo(1, "2", p3 = 3.0) - foo(p1 = 1, p2 = "2", 3.0) + foo(p1 = 1, p2 = "2", 3.0) foo(1, p3 = 2.0, "") foo(1, p3 = 2.0, 3.0) diff --git a/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/simple.fir.kt b/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/simple.fir.kt index eb0a087d90d..fa71be4dd76 100644 --- a/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/simple.fir.kt +++ b/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/simple.fir.kt @@ -9,11 +9,11 @@ fun foo( ) {} fun main() { - foo(p1 = 1, "2", 3.0) - foo(1, p2 = "2", 3.0) + foo(p1 = 1, "2", 3.0) + foo(1, p2 = "2", 3.0) foo(1, "2", p3 = 3.0) - foo(p1 = 1, p2 = "2", 3.0) + foo(p1 = 1, p2 = "2", 3.0) foo(1, p3 = 2.0, "") foo(1, p3 = 2.0, 3.0) diff --git a/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/varargs.fir.kt b/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/varargs.fir.kt index 2cd69ee3731..87a05f77887 100644 --- a/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/varargs.fir.kt +++ b/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/varargs.fir.kt @@ -29,16 +29,16 @@ fun foo4( fun main() { foo1(1, 2, p2 = "3", 4.0) - foo1(p1 = intArrayOf(1, 2), "3", p3 = 4.0) + foo1(p1 = intArrayOf(1, 2), "3", p3 = 4.0) foo1(p2 = "3", 4.0) - foo2(p1 = 1, "2", "3", p3 = 4.0) - foo2(1, p2 = arrayOf("2", "3"), 4.0) + foo2(p1 = 1, "2", "3", p3 = 4.0) + foo2(1, p2 = arrayOf("2", "3"), 4.0) foo2(1, p3 = 3.0) - foo3(p1 = 1, "2", 3.0, 4.0) - foo3(p1 = 1, "2", p3 = doubleArrayOf(3.0, 4.0)) + foo3(p1 = 1, "2", 3.0, 4.0) + foo3(p1 = 1, "2", p3 = doubleArrayOf(3.0, 4.0)) foo4(p1 = 1, "2", "3", p3 = 4.0, 5) foo4(1, "2", "3", p3 = 4.0, 5) @@ -50,8 +50,8 @@ fun main() { foo2(1, p3 = 2.0, "4") foo2(1, p3 = 2.0, *arrayOf("3", "4")) - foo2(1, p3 = 2.0, p2 = arrayOf("3", "4")) + foo2(1, p3 = 2.0, p2 = arrayOf("3", "4")) foo3(1, p3 = doubleArrayOf(2.0, 3.0), "4") - foo3(1, p3 = doubleArrayOf(2.0, 3.0), p2 = "4") + foo3(1, p3 = doubleArrayOf(2.0, 3.0), p2 = "4") } diff --git a/compiler/testData/diagnostics/tests/resolve/newLineLambda.fir.kt b/compiler/testData/diagnostics/tests/resolve/newLineLambda.fir.kt index 3646efb9384..a6deacbc8f9 100644 --- a/compiler/testData/diagnostics/tests/resolve/newLineLambda.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/newLineLambda.fir.kt @@ -96,7 +96,7 @@ fun testTwoLambdas() { ) fun bar(): () -> Unit { - twoLambdaArgs() + twoLambdaArgs() {} {} diff --git a/compiler/testData/diagnostics/tests/resolve/overloadConflicts/varargsInDifferentPositions.fir.kt b/compiler/testData/diagnostics/tests/resolve/overloadConflicts/varargsInDifferentPositions.fir.kt index ba34c23519c..a78ef79e23e 100644 --- a/compiler/testData/diagnostics/tests/resolve/overloadConflicts/varargsInDifferentPositions.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/overloadConflicts/varargsInDifferentPositions.fir.kt @@ -8,6 +8,6 @@ fun overloadedFun(arg: String, vararg args: String) = X1 fun overloadedFun(arg: String, vararg args: String, flag: Boolean = true) = X2 val test1a: X1 = overloadedFun("", "") -val test1b: X1 = overloadedFun("", args = "") +val test1b: X1 = overloadedFun("", args = "") val test1c: X2 = overloadedFun("", "", "", flag = true) diff --git a/compiler/testData/diagnostics/tests/resolve/overloadConflicts/varargsMixed.fir.kt b/compiler/testData/diagnostics/tests/resolve/overloadConflicts/varargsMixed.fir.kt index 240eac7e794..d6cb070fa8a 100644 --- a/compiler/testData/diagnostics/tests/resolve/overloadConflicts/varargsMixed.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/overloadConflicts/varargsMixed.fir.kt @@ -9,5 +9,5 @@ fun overloadedFun5(s: String, vararg ss: String) = X2 val test1 = overloadedFun5("") val test2 = overloadedFun5("", "") -val test3: X2 = overloadedFun5(s = "", ss = "") -val test4: X1 = overloadedFun5(ss = "") \ No newline at end of file +val test3: X2 = overloadedFun5(s = "", ss = "") +val test4: X1 = overloadedFun5(ss = "") \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/secondaryConstructors/varargsInDelegationCallToPrimary.fir.kt b/compiler/testData/diagnostics/tests/secondaryConstructors/varargsInDelegationCallToPrimary.fir.kt index 8dd2ca4f47f..5ade214712b 100644 --- a/compiler/testData/diagnostics/tests/secondaryConstructors/varargsInDelegationCallToPrimary.fir.kt +++ b/compiler/testData/diagnostics/tests/secondaryConstructors/varargsInDelegationCallToPrimary.fir.kt @@ -2,7 +2,7 @@ fun array(vararg x: T): Array = null!! open class B(vararg y: String) { - constructor(x: Int): this(x.toString(), *array("1"), "2") + constructor(x: Int): this(x.toString(), *array("1"), "2") } class A : B { diff --git a/compiler/testData/diagnostics/tests/secondaryConstructors/varargsInDelegationCallToSecondary.fir.kt b/compiler/testData/diagnostics/tests/secondaryConstructors/varargsInDelegationCallToSecondary.fir.kt index 1baecabc09f..604684c9443 100644 --- a/compiler/testData/diagnostics/tests/secondaryConstructors/varargsInDelegationCallToSecondary.fir.kt +++ b/compiler/testData/diagnostics/tests/secondaryConstructors/varargsInDelegationCallToSecondary.fir.kt @@ -13,5 +13,5 @@ class A : B { val b1 = B() val b2 = B("1", "2", "3") -val b3 = B("1", *array("2", "3"), "4") +val b3 = B("1", *array("2", "3"), "4") val b4 = B(1) diff --git a/compiler/testData/diagnostics/tests/varargs/assignArrayToVararagInNamedForm_1_3.fir.kt b/compiler/testData/diagnostics/tests/varargs/assignArrayToVararagInNamedForm_1_3.fir.kt index f69ba67ed63..fb04b9988b0 100644 --- a/compiler/testData/diagnostics/tests/varargs/assignArrayToVararagInNamedForm_1_3.fir.kt +++ b/compiler/testData/diagnostics/tests/varargs/assignArrayToVararagInNamedForm_1_3.fir.kt @@ -12,11 +12,11 @@ fun foo() {} fun test_fun(s: String, arr: Array) { withVararg(arr) // Error withVararg(*arr) // OK - withVararg(s = arr) // Error + withVararg(s = arr) // Error withVararg(s = *arr) // OK withVararg(s) // OK - withVararg(s = s) // Error + withVararg(s = s) // Error } fun test_ann(s: String, arr: Array) { diff --git a/compiler/testData/diagnostics/tests/varargs/assignArrayToVararagInNamedForm_1_4.fir.kt b/compiler/testData/diagnostics/tests/varargs/assignArrayToVararagInNamedForm_1_4.fir.kt index c58c5e821e7..971e060e747 100644 --- a/compiler/testData/diagnostics/tests/varargs/assignArrayToVararagInNamedForm_1_4.fir.kt +++ b/compiler/testData/diagnostics/tests/varargs/assignArrayToVararagInNamedForm_1_4.fir.kt @@ -12,11 +12,11 @@ fun foo() {} fun test_fun(s: String, arr: Array) { withVararg(arr) // Error withVararg(*arr) // OK - withVararg(s = arr) // OK + withVararg(s = arr) // OK withVararg(s = *arr) // Warning withVararg(s) // OK - withVararg(s = s) // Error + withVararg(s = s) // Error } fun test_ann(s: String, arr: Array) { diff --git a/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormFunDeprecation_after.fir.kt b/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormFunDeprecation_after.fir.kt index d3ec06df05f..3a7e5acc4ce 100644 --- a/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormFunDeprecation_after.fir.kt +++ b/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormFunDeprecation_after.fir.kt @@ -7,27 +7,27 @@ fun foo(vararg s: Int) {} open class Cls(vararg p: Long) fun test(i: IntArray) { - foo(s = 1) - foo(s = i) + foo(s = 1) + foo(s = i) foo(s = *i) - foo(s = intArrayOf(1)) + foo(s = intArrayOf(1)) foo(s = *intArrayOf(1)) foo(1) - Cls(p = 1) + Cls(p = 1) - class Sub : Cls(p = 1) + class Sub : Cls(p = 1) - val c = object : Cls(p = 1) {} + val c = object : Cls(p = 1) {} - foo(s = *intArrayOf(elements = 1)) + foo(s = *intArrayOf(elements = 1)) } fun anyFoo(vararg a: Any) {} fun testAny() { - anyFoo(a = "") + anyFoo(a = "") anyFoo(a = arrayOf("")) anyFoo(a = *arrayOf("")) } @@ -35,12 +35,12 @@ fun testAny() { fun genFoo(vararg t: T) {} fun testGen() { - genFoo(t = 1) - genFoo(t = null) + genFoo(t = 1) + genFoo(t = null) genFoo>(t = arrayOf()) genFoo>(t = *arrayOf(arrayOf())) - genFoo(t = "") + genFoo(t = "") genFoo(t = arrayOf("")) genFoo(t = *arrayOf("")) } @@ -49,12 +49,12 @@ fun manyFoo(vararg v: Int) {} fun manyFoo(vararg s: String) {} fun testMany(a: Any) { - manyFoo(v = 1) - manyFoo(s = "") + manyFoo(v = 1) + manyFoo(s = "") manyFoo(a) manyFoo(v = a) manyFoo(s = a) - manyFoo(v = a as Int) - manyFoo(s = a as String) + manyFoo(v = a as Int) + manyFoo(s = a as String) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormFunDeprecation_before.fir.kt b/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormFunDeprecation_before.fir.kt index 1111b59ba73..6ef4808f15d 100644 --- a/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormFunDeprecation_before.fir.kt +++ b/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormFunDeprecation_before.fir.kt @@ -7,27 +7,27 @@ fun foo(vararg s: Int) {} open class Cls(vararg p: Long) fun test(i: IntArray) { - foo(s = 1) - foo(s = i) + foo(s = 1) + foo(s = i) foo(s = *i) - foo(s = intArrayOf(1)) + foo(s = intArrayOf(1)) foo(s = *intArrayOf(1)) foo(1) - Cls(p = 1) + Cls(p = 1) - class Sub : Cls(p = 1) + class Sub : Cls(p = 1) - val c = object : Cls(p = 1) {} + val c = object : Cls(p = 1) {} - foo(s = *intArrayOf(elements = 1)) + foo(s = *intArrayOf(elements = 1)) } fun anyFoo(vararg a: Any) {} fun testAny() { - anyFoo(a = "") + anyFoo(a = "") anyFoo(a = arrayOf("")) anyFoo(a = *arrayOf("")) } @@ -35,12 +35,12 @@ fun testAny() { fun genFoo(vararg t: T) {} fun testGen() { - genFoo(t = 1) - genFoo(t = null) + genFoo(t = 1) + genFoo(t = null) genFoo>(t = arrayOf()) genFoo>(t = *arrayOf(arrayOf())) - genFoo(t = "") + genFoo(t = "") genFoo(t = arrayOf("")) genFoo(t = *arrayOf("")) } @@ -49,12 +49,12 @@ fun manyFoo(vararg v: Int) {} fun manyFoo(vararg s: String) {} fun testMany(a: Any) { - manyFoo(v = 1) - manyFoo(s = "") + manyFoo(v = 1) + manyFoo(s = "") manyFoo(a) manyFoo(v = a) manyFoo(s = a) - manyFoo(v = a as Int) - manyFoo(s = a as String) + manyFoo(v = a as Int) + manyFoo(s = a as String) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/varargs/noAssigningArraysToVarargsFeature.fir.kt b/compiler/testData/diagnostics/tests/varargs/noAssigningArraysToVarargsFeature.fir.kt index a3827f727a8..0847abdf8e8 100644 --- a/compiler/testData/diagnostics/tests/varargs/noAssigningArraysToVarargsFeature.fir.kt +++ b/compiler/testData/diagnostics/tests/varargs/noAssigningArraysToVarargsFeature.fir.kt @@ -45,5 +45,5 @@ fun foo(vararg i: Int) {} @Ann(s = "value") fun dep1() { - foo(i = 1) + foo(i = 1) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/varargs/prohibitAssigningSingleElementsInNamedForm.fir.kt b/compiler/testData/diagnostics/tests/varargs/prohibitAssigningSingleElementsInNamedForm.fir.kt index 7a8a4abb089..be0d598dc42 100644 --- a/compiler/testData/diagnostics/tests/varargs/prohibitAssigningSingleElementsInNamedForm.fir.kt +++ b/compiler/testData/diagnostics/tests/varargs/prohibitAssigningSingleElementsInNamedForm.fir.kt @@ -15,6 +15,6 @@ fun f2() {} fun foo(vararg ints: Int) {} fun test() { - foo(ints = 1) + foo(ints = 1) foo(ints = *intArrayOf(1)) } diff --git a/compiler/testData/ir/irText/expressions/vararg.fir.txt b/compiler/testData/ir/irText/expressions/vararg.fir.txt index 1d876b445ca..e92721f4044 100644 --- a/compiler/testData/ir/irText/expressions/vararg.fir.txt +++ b/compiler/testData/ir/irText/expressions/vararg.fir.txt @@ -24,15 +24,19 @@ FILE fqName: fileName:/vararg.kt RETURN type=kotlin.Nothing from='public final fun (): kotlin.Array declared in ' GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.Array visibility:private [final,static]' type=kotlin.Array origin=null PROPERTY name:test3 visibility:public modality:FINAL [val] - FIELD PROPERTY_BACKING_FIELD name:test3 type:IrErrorType visibility:private [final,static] + FIELD PROPERTY_BACKING_FIELD name:test3 type:kotlin.Array visibility:private [final,static] EXPRESSION_BODY - ERROR_CALL 'Unresolved reference: #' type=IrErrorType - CONST String type=kotlin.String value="0" - CALL 'public final fun (): kotlin.Array declared in ' type=kotlin.Array origin=null - CALL 'public final fun (): kotlin.Array declared in ' type=kotlin.Array origin=null - CONST String type=kotlin.String value="4" - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:IrErrorType + 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="0" + SPREAD_ELEMENT + CALL 'public final fun (): kotlin.Array declared in ' type=kotlin.Array origin=null + SPREAD_ELEMENT + CALL 'public final fun (): kotlin.Array declared in ' type=kotlin.Array origin=null + CONST String type=kotlin.String value="4" + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.Array correspondingProperty: PROPERTY name:test3 visibility:public modality:FINAL [val] BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): IrErrorType declared in ' - GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test3 type:IrErrorType visibility:private [final,static]' type=IrErrorType origin=null + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Array declared in ' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test3 type:kotlin.Array visibility:private [final,static]' type=kotlin.Array origin=null diff --git a/core/util.runtime/src/org/jetbrains/kotlin/utils/addToStdlib.kt b/core/util.runtime/src/org/jetbrains/kotlin/utils/addToStdlib.kt index c364f463a81..9fc250e2696 100644 --- a/core/util.runtime/src/org/jetbrains/kotlin/utils/addToStdlib.kt +++ b/core/util.runtime/src/org/jetbrains/kotlin/utils/addToStdlib.kt @@ -146,3 +146,6 @@ inline fun > Iterable.flatMapToNullable(des } return destination } + +fun > min(a: E, b: E): E = if (a < b) a else b +fun > min(a: E, b: E): E = if (a < b) a else b \ No newline at end of file diff --git a/idea/testData/resolve/references/invoke/lambdaAndParens.kt b/idea/testData/resolve/references/invoke/lambdaAndParens.kt index a23abb74304..af01c7f93e9 100644 --- a/idea/testData/resolve/references/invoke/lambdaAndParens.kt +++ b/idea/testData/resolve/references/invoke/lambdaAndParens.kt @@ -1,3 +1,5 @@ +// IGNORE_FIR + class Foo { fun invoke(vararg a: Any) {} } diff --git a/idea/testData/resolve/references/invoke/lambdaNoPar.kt b/idea/testData/resolve/references/invoke/lambdaNoPar.kt index cd6e79d71c2..253157780a9 100644 --- a/idea/testData/resolve/references/invoke/lambdaNoPar.kt +++ b/idea/testData/resolve/references/invoke/lambdaNoPar.kt @@ -1,3 +1,5 @@ +// IGNORE_FIR + class Foo { fun invoke(vararg a: Any) {} } diff --git a/idea/testData/resolve/references/invoke/lambdaNoParLabel.kt b/idea/testData/resolve/references/invoke/lambdaNoParLabel.kt index 0ae77948e39..6e3ba435282 100644 --- a/idea/testData/resolve/references/invoke/lambdaNoParLabel.kt +++ b/idea/testData/resolve/references/invoke/lambdaNoParLabel.kt @@ -1,3 +1,5 @@ +// IGNORE_FIR + class Foo { fun invoke(vararg a: Any) {} } diff --git a/idea/testData/resolve/references/invoke/lambdaNoParRCurly.kt b/idea/testData/resolve/references/invoke/lambdaNoParRCurly.kt index 1dc808f0527..1d52891066c 100644 --- a/idea/testData/resolve/references/invoke/lambdaNoParRCurly.kt +++ b/idea/testData/resolve/references/invoke/lambdaNoParRCurly.kt @@ -1,3 +1,5 @@ +// IGNORE_FIR + class Foo { fun invoke(vararg a: Any) {} } diff --git a/idea/testData/resolve/references/invoke/nonemptyLambdaRPar.kt b/idea/testData/resolve/references/invoke/nonemptyLambdaRPar.kt index 2ce67a054ed..36dfb64d544 100644 --- a/idea/testData/resolve/references/invoke/nonemptyLambdaRPar.kt +++ b/idea/testData/resolve/references/invoke/nonemptyLambdaRPar.kt @@ -1,3 +1,5 @@ +// IGNORE_FIR + class Foo { fun invoke(vararg a: Any) {} }