From 950ab0159651ebba9de7c766b6a1955dd57f63fd Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Mon, 16 Mar 2020 14:30:43 +0100 Subject: [PATCH] Avoid substitution and type approximation for simple calls #KT-37392 fixed --- .../tower/KotlinToResolvedCallTransformer.kt | 41 +++++++++++-------- .../resolve/calls/inference/InferenceUtils.kt | 4 +- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt index d58f10a1cec..338beafcbcb 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt @@ -773,35 +773,28 @@ class NewResolvedCallImpl( getSubstitutorWithoutFlexibleTypes(substitutor, explicitTypeArguments), ) } - is FunctionDescriptor -> candidateDescriptor.substituteInferredVariablesAndApproximate(substitutor) + is FunctionDescriptor -> { + candidateDescriptor.substituteInferredVariablesAndApproximate(substitutor, candidateDescriptor.isNotSimpleCall()) + } is PropertyDescriptor -> { - if (candidateDescriptor.typeParameters.isNotEmpty()) + if (candidateDescriptor.isNotSimpleCall()) { candidateDescriptor.substituteInferredVariablesAndApproximate(substitutor) - else { - val shouldForceApproximationAndSubstitution = candidateDescriptor.returnType?.let { type -> - type.contains { - it is NewCapturedType || - it.constructor is IntegerLiteralTypeConstructor || - it is DefinitelyNotNullType || - it is StubType - } - } ?: false - - if (shouldForceApproximationAndSubstitution) - candidateDescriptor.substituteInferredVariablesAndApproximate(substitutor) - else - candidateDescriptor + } else { + candidateDescriptor } } else -> candidateDescriptor } - private fun CallableDescriptor.substituteInferredVariablesAndApproximate(substitutor: NewTypeSubstitutor?): CallableDescriptor { + private fun CallableDescriptor.substituteInferredVariablesAndApproximate( + substitutor: NewTypeSubstitutor?, + shouldApproximate: Boolean = true + ): CallableDescriptor { val inferredTypeVariablesSubstitutor = substitutor ?: FreshVariableNewTypeSubstitutor.Empty val compositeSubstitutor = inferredTypeVariablesSubstitutor.composeWith(resolvedCallAtom.knownParametersSubstitutor) return substitute(resolvedCallAtom.freshVariablesSubstitutor) - .substituteAndApproximateTypes(compositeSubstitutor, typeApproximator) + .substituteAndApproximateTypes(compositeSubstitutor, if (shouldApproximate) typeApproximator else null) } fun getArgumentTypeForConstantConvertedArgument(valueArgument: ValueArgument): IntegerValueTypeConstant? { @@ -914,3 +907,15 @@ fun NewResolvedCallImpl<*>.hasInferredReturnType(): Boolean { val returnType = this.resultingDescriptor.returnType ?: return false return !returnType.contains { ErrorUtils.isUninferredParameter(it) } } + +private fun CallableMemberDescriptor.isNotSimpleCall(): Boolean = + typeParameters.isNotEmpty() || + (returnType?.let { type -> + type.contains { + it is NewCapturedType || + it.constructor is IntegerLiteralTypeConstructor || + it is DefinitelyNotNullType || + it is StubType + } + } ?: false) + diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt index 3eb46710ce5..67795576c0a 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt @@ -80,14 +80,14 @@ fun CallableDescriptor.substitute(substitutor: NewTypeSubstitutor): CallableDesc fun CallableDescriptor.substituteAndApproximateTypes( substitutor: NewTypeSubstitutor, - typeApproximator: TypeApproximator + typeApproximator: TypeApproximator? ): CallableDescriptor { val wrappedSubstitution = object : TypeSubstitution() { override fun get(key: KotlinType): TypeProjection? = null override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) = substitutor.safeSubstitute(topLevelType.unwrap()).let { substitutedType -> - typeApproximator.approximateToSuperType( + typeApproximator?.approximateToSuperType( substitutedType, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference ) ?: substitutedType