[NI] Use only receiver from coroutine call to mark postponed variable

This commit is contained in:
Mikhail Zarechenskiy
2018-04-25 12:26:48 +03:00
parent 59c4b9ad2f
commit e0ca3421ca
4 changed files with 21 additions and 10 deletions
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.resolve.calls.tower package org.jetbrains.kotlin.resolve.calls.tower
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
@@ -31,6 +32,7 @@ import org.jetbrains.kotlin.resolve.calls.model.CallableReferenceKotlinCallArgum
import org.jetbrains.kotlin.resolve.calls.model.KotlinCall import org.jetbrains.kotlin.resolve.calls.model.KotlinCall
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument
import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class KotlinResolutionStatelessCallbacksImpl( class KotlinResolutionStatelessCallbacksImpl(
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.NonFixedType import org.jetbrains.kotlin.types.NonFixedType
import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.types.UnwrappedType
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.resolve.calls.components package org.jetbrains.kotlin.resolve.calls.components
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
@@ -192,17 +193,24 @@ internal object CreateFreshVariablesSubstitutor : ResolutionPart() {
} }
} }
internal object InferLaterInitializerResolutionPart : ResolutionPart() { internal object PostponedVariablesInitializerResolutionPart : ResolutionPart() {
override fun KotlinResolutionCandidate.process(workIndex: Int) { override fun KotlinResolutionCandidate.process(workIndex: Int) {
resolvedCall.argumentToCandidateParameter val typesForCoroutineCall = resolvedCall.argumentToCandidateParameter
.filter { (argument, parameter) -> callComponents.statelessCallbacks.isCoroutineCall(argument, parameter) } .filter { (argument, parameter) -> callComponents.statelessCallbacks.isCoroutineCall(argument, parameter) }
.flatMap { (_, parameter) -> .mapNotNull { it.value.type.getReceiverTypeFromFunctionType() }
resolvedCall.substitutor.freshVariables.filter { variable ->
parameter.type.contains { it.constructor == variable.originalTypeParameter.typeConstructor } if (typesForCoroutineCall.isEmpty()) return
}
for (freshVariable in resolvedCall.substitutor.freshVariables) {
val isPostponedVariable = typesForCoroutineCall.any { typeForCoroutineCall ->
typeForCoroutineCall.contains { it.constructor == freshVariable.originalTypeParameter.typeConstructor }
} }
.distinct()
.forEach { csBuilder.markPostponedVariable(it) } if (isPostponedVariable) {
csBuilder.markPostponedVariable(freshVariable)
}
}
} }
} }
@@ -192,7 +192,7 @@ enum class KotlinCallKind(vararg resolutionPart: ResolutionPart) {
CreateFreshVariablesSubstitutor, CreateFreshVariablesSubstitutor,
CheckExplicitReceiverKindConsistency, CheckExplicitReceiverKindConsistency,
CheckReceivers, CheckReceivers,
InferLaterInitializerResolutionPart PostponedVariablesInitializerResolutionPart
), ),
FUNCTION( FUNCTION(
CheckInstantiationOfAbstractClass, CheckInstantiationOfAbstractClass,
@@ -207,7 +207,7 @@ enum class KotlinCallKind(vararg resolutionPart: ResolutionPart) {
CheckReceivers, CheckReceivers,
CheckArguments, CheckArguments,
CheckExternalArgument, CheckExternalArgument,
InferLaterInitializerResolutionPart PostponedVariablesInitializerResolutionPart
), ),
INVOKE(*FUNCTION.resolutionSequence.toTypedArray()), INVOKE(*FUNCTION.resolutionSequence.toTypedArray()),
UNSUPPORTED(); UNSUPPORTED();