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.
This commit is contained in:
Jinseong Jeon
2020-02-05 21:28:17 -08:00
committed by Dmitry Petrov
parent f782ea075b
commit 5a49ccac76
3 changed files with 16 additions and 3 deletions
@@ -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<NewResolvedCallImpl<*>>()?.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
@@ -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
@@ -1,6 +1,5 @@
// !LANGUAGE: +NewInference +SamConversionForKotlinFunctions +SamConversionPerArgument
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// FILE: Test.java