From 5a49ccac760d479fd3830d4dc0823448c9d952ea Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Wed, 5 Feb 2020 21:28:17 -0800 Subject: [PATCH] JVM_IR: Relax bailout condition for SAM conversion generation. Previously, resolved call is expected to have SAM converted argument map if SamConversionPerArgument is enabled. However, if SAM argument is followed by vararg parameter and an array _without_ a spread operator is passed, New Inference left a type mismatch error on a resolved call, which made that resolved candidate filtered out. Instead, another resolution result wihtout SAM converted arugment map will be provided. All other logics, such as adding SAM conversion type op and lowering SAM conversion and/or call references, are already there for resolved calls without SAM converted argument map. This change just relaxes the bailout condition so that array passed to vararg after SAM argument can be handled in JVM IR. --- .../generators/ArgumentsGenerationUtils.kt | 16 +++++++++++++++- .../resolve/calls/components/ArgumentsUtils.kt | 2 +- .../box/sam/arrayAsVarargAfterSamArgument.kt | 1 - 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt index f5efe61b38b..fa0eda92b5a 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt @@ -36,6 +36,8 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getSuperCallExpression import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall +import org.jetbrains.kotlin.resolve.calls.components.isArrayOrArrayLiteral +import org.jetbrains.kotlin.resolve.calls.components.isVararg import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl import org.jetbrains.kotlin.resolve.scopes.receivers.* @@ -43,6 +45,7 @@ import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeProjectionImpl import org.jetbrains.kotlin.types.TypeSubstitutor import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.utils.addToStdlib.safeAs import kotlin.math.max import kotlin.math.min @@ -425,6 +428,17 @@ fun StatementGenerator.generateSamConversionForValueArgumentsIfRequired(call: Ca } val partialSamConversionIsSupported = context.languageVersionSettings.supportsFeature(LanguageFeature.SamConversionPerArgument) + val resolvedCallArguments = resolvedCall.safeAs>()?.argumentMappingByOriginal?.values + assert(resolvedCallArguments == null || resolvedCallArguments.size == underlyingValueParameters.size) { + "Mismatching resolved call arguments:\n" + + "${resolvedCallArguments?.size} != ${underlyingValueParameters.size}" + } + val isArrayAssignedToVararg: Boolean = resolvedCallArguments != null && + (underlyingValueParameters zip resolvedCallArguments).any { (param, arg) -> + param.isVararg && arg is ResolvedCallArgument.SimpleArgument && arg.callArgument.isArrayOrArrayLiteral() + } + val expectSamConvertedArgumentToBeAvailableInResolvedCall = partialSamConversionIsSupported && !isArrayAssignedToVararg + val substitutionContext = call.original.typeArguments.entries.associate { (typeParameterDescriptor, typeArgument) -> underlyingDescriptor.typeParameters[typeParameterDescriptor.index].typeConstructor to TypeProjectionImpl(typeArgument) } @@ -434,7 +448,7 @@ fun StatementGenerator.generateSamConversionForValueArgumentsIfRequired(call: Ca val underlyingValueParameter = underlyingValueParameters[i] val originalUnderlyingParameterType = underlyingValueParameter.original.type - if (partialSamConversionIsSupported && resolvedCall is NewResolvedCallImpl<*>) { + if (expectSamConvertedArgumentToBeAvailableInResolvedCall && resolvedCall is NewResolvedCallImpl<*>) { // TODO support SAM conversion of varargs val argument = resolvedCall.valueArguments[originalValueParameters[i]]?.arguments?.singleOrNull() ?: continue resolvedCall.getExpectedTypeForSamConvertedArgument(argument) ?: continue diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsUtils.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsUtils.kt index 939e51585a0..74b2f569e74 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsUtils.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsUtils.kt @@ -135,7 +135,7 @@ private fun KotlinCallArgument.isArrayAssignedAsNamedArgumentInFunction( return this.isArrayOrArrayLiteral() } -private fun KotlinCallArgument.isArrayOrArrayLiteral(): Boolean { +fun KotlinCallArgument.isArrayOrArrayLiteral(): Boolean { if (this is CollectionLiteralKotlinCallArgument) return true if (this !is SimpleKotlinCallArgument) return false diff --git a/compiler/testData/codegen/box/sam/arrayAsVarargAfterSamArgument.kt b/compiler/testData/codegen/box/sam/arrayAsVarargAfterSamArgument.kt index cc7f065a333..854cd21e04c 100644 --- a/compiler/testData/codegen/box/sam/arrayAsVarargAfterSamArgument.kt +++ b/compiler/testData/codegen/box/sam/arrayAsVarargAfterSamArgument.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +NewInference +SamConversionForKotlinFunctions +SamConversionPerArgument // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // FILE: Test.java