[NI] Don't use only platform specific checks for FIC in inference

This commit is contained in:
Mikhail Zarechenskiy
2020-01-24 20:09:35 +03:00
parent 7e85674c61
commit 00469712d1
14 changed files with 220 additions and 67 deletions
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.container.DefaultImplementation
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
@@ -17,6 +18,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.results.SimpleConstraintSystem
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.StubType
import org.jetbrains.kotlin.types.UnwrappedType
@@ -80,8 +82,14 @@ interface SamConversionTransformer {
fun shouldRunSamConversionForFunction(candidate: CallableDescriptor): Boolean
fun isPossibleSamType(samType: KotlinType): Boolean
object Empty : SamConversionTransformer {
override fun getFunctionTypeForPossibleSamType(possibleSamType: UnwrappedType): UnwrappedType? = null
override fun shouldRunSamConversionForFunction(candidate: CallableDescriptor): Boolean = false
override fun isPossibleSamType(samType: KotlinType): Boolean {
val descriptor = samType.constructor.declarationDescriptor
return descriptor is ClassDescriptor && descriptor.isFun
}
}
}
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.*
import org.jetbrains.kotlin.resolve.calls.tower.InfixCallNoInfixModifier
import org.jetbrains.kotlin.resolve.calls.tower.InvokeConventionCallNoOperatorModifier
import org.jetbrains.kotlin.resolve.calls.tower.VisibilityError
import org.jetbrains.kotlin.resolve.sam.getFunctionTypeForPossibleSamType
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.contains
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
@@ -311,7 +312,9 @@ private fun KotlinResolutionCandidate.getExpectedTypeWithSAMConversion(
!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitVarargAsArrayAfterSamArgument)
if (generatingAdditionalSamCandidateIsEnabled) return null
if (!callComponents.samConversionTransformer.shouldRunSamConversionForFunction(resolvedCall.candidateDescriptor)) return null
if (!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.SamConversionForKotlinFunctions)) {
if (!callComponents.samConversionTransformer.shouldRunSamConversionForFunction(resolvedCall.candidateDescriptor)) return null
}
val argumentIsFunctional = when (argument) {
is SimpleKotlinCallArgument -> argument.receiver.stableType.isFunctionType
@@ -321,11 +324,14 @@ private fun KotlinResolutionCandidate.getExpectedTypeWithSAMConversion(
if (!argumentIsFunctional) return null
val originalExpectedType = argument.getExpectedType(candidateParameter.original, callComponents.languageVersionSettings)
if (!callComponents.samConversionTransformer.isPossibleSamType(originalExpectedType)) return null
val convertedTypeByOriginal =
callComponents.samConversionTransformer.getFunctionTypeForPossibleSamType(originalExpectedType) ?: return null
callComponents.samConversionResolver.getFunctionTypeForPossibleSamType(originalExpectedType) ?: return null
val candidateExpectedType = argument.getExpectedType(candidateParameter, callComponents.languageVersionSettings)
val convertedTypeByCandidate = callComponents.samConversionTransformer.getFunctionTypeForPossibleSamType(candidateExpectedType)
val convertedTypeByCandidate = callComponents.samConversionResolver.getFunctionTypeForPossibleSamType(candidateExpectedType)
assert(candidateExpectedType.constructor == originalExpectedType.constructor && convertedTypeByCandidate != null) {
"If original type is SAM type, then candidate should have same type constructor and corresponding function type\n" +
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.tower.*
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDynamicExtensionAnnotation
import org.jetbrains.kotlin.resolve.sam.SamConversionResolver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.TypeSubstitutor
@@ -44,6 +45,7 @@ class KotlinCallComponents(
val builtIns: KotlinBuiltIns,
val languageVersionSettings: LanguageVersionSettings,
val samConversionTransformer: SamConversionTransformer,
val samConversionResolver: SamConversionResolver,
val kotlinTypeChecker: NewKotlinTypeChecker
)