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:
committed by
Dmitry Petrov
parent
f782ea075b
commit
5a49ccac76
+15
-1
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user