From 6c44b6b85947694160b25f4ad8088b260cad926a Mon Sep 17 00:00:00 2001 From: Dmitry Savvinov Date: Thu, 4 Jul 2019 17:35:24 +0300 Subject: [PATCH] [API Usage] Refine type of lambda's receiver in NI It's needed because of lambda's receiver is not an expression and we can not refine it in usual way in TypingVisitor --- .../tower/KotlinResolutionCallbacksImpl.kt | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinResolutionCallbacksImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinResolutionCallbacksImpl.kt index 049044d0ba9..6ac93fef347 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinResolutionCallbacksImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinResolutionCallbacksImpl.kt @@ -44,6 +44,7 @@ import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices import org.jetbrains.kotlin.types.expressions.KotlinTypeInfo +import org.jetbrains.kotlin.types.refinement.TypeRefinement import org.jetbrains.kotlin.types.typeUtil.isUnit import org.jetbrains.kotlin.types.typeUtil.makeNullable import org.jetbrains.kotlin.utils.addIfNotNull @@ -130,8 +131,22 @@ class KotlinResolutionCallbacksImpl( trace.record(BindingContext.NEW_INFERENCE_LAMBDA_INFO, psiCallArgument.ktFunction, lambdaInfo) val builtIns = outerCallContext.scope.ownerDescriptor.builtIns + + // We have to refine receiverType because resolve inside lambda needs proper scope from receiver, + // and for implicit receivers there are no expression which type would've been refined in ExpTypingVisitor + // Relevant test: multiplatformTypeRefinement/lambdas + // + // It doesn't happen in similar cases with other implicit receivers (e.g., with scope of extension receiver + // inside extension function) because during resolution of types we correctly discriminate headers + // + // Also note that refining the whole type might be undesired because sometimes it contains NO_EXPECTED_TYPE + // which throws exceptions on attempt to call equals + val refinedReceiverType = receiverType?.let { + @UseExperimental(TypeRefinement::class) callComponents.kotlinTypeChecker.kotlinTypeRefiner.refineType(it) + } + val expectedType = createFunctionType( - builtIns, annotations, receiverType, parameters, null, + builtIns, annotations, refinedReceiverType, parameters, null, lambdaInfo.expectedType, isSuspend )