Avoid substitution and type approximation for simple calls
#KT-37392 fixed
This commit is contained in:
+23
-18
@@ -773,35 +773,28 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
|||||||
getSubstitutorWithoutFlexibleTypes(substitutor, explicitTypeArguments),
|
getSubstitutorWithoutFlexibleTypes(substitutor, explicitTypeArguments),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is FunctionDescriptor -> candidateDescriptor.substituteInferredVariablesAndApproximate(substitutor)
|
is FunctionDescriptor -> {
|
||||||
|
candidateDescriptor.substituteInferredVariablesAndApproximate(substitutor, candidateDescriptor.isNotSimpleCall())
|
||||||
|
}
|
||||||
is PropertyDescriptor -> {
|
is PropertyDescriptor -> {
|
||||||
if (candidateDescriptor.typeParameters.isNotEmpty())
|
if (candidateDescriptor.isNotSimpleCall()) {
|
||||||
candidateDescriptor.substituteInferredVariablesAndApproximate(substitutor)
|
candidateDescriptor.substituteInferredVariablesAndApproximate(substitutor)
|
||||||
else {
|
} else {
|
||||||
val shouldForceApproximationAndSubstitution = candidateDescriptor.returnType?.let { type ->
|
candidateDescriptor
|
||||||
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 inferredTypeVariablesSubstitutor = substitutor ?: FreshVariableNewTypeSubstitutor.Empty
|
||||||
val compositeSubstitutor = inferredTypeVariablesSubstitutor.composeWith(resolvedCallAtom.knownParametersSubstitutor)
|
val compositeSubstitutor = inferredTypeVariablesSubstitutor.composeWith(resolvedCallAtom.knownParametersSubstitutor)
|
||||||
|
|
||||||
return substitute(resolvedCallAtom.freshVariablesSubstitutor)
|
return substitute(resolvedCallAtom.freshVariablesSubstitutor)
|
||||||
.substituteAndApproximateTypes(compositeSubstitutor, typeApproximator)
|
.substituteAndApproximateTypes(compositeSubstitutor, if (shouldApproximate) typeApproximator else null)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getArgumentTypeForConstantConvertedArgument(valueArgument: ValueArgument): IntegerValueTypeConstant? {
|
fun getArgumentTypeForConstantConvertedArgument(valueArgument: ValueArgument): IntegerValueTypeConstant? {
|
||||||
@@ -914,3 +907,15 @@ fun NewResolvedCallImpl<*>.hasInferredReturnType(): Boolean {
|
|||||||
val returnType = this.resultingDescriptor.returnType ?: return false
|
val returnType = this.resultingDescriptor.returnType ?: return false
|
||||||
return !returnType.contains { ErrorUtils.isUninferredParameter(it) }
|
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)
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -80,14 +80,14 @@ fun CallableDescriptor.substitute(substitutor: NewTypeSubstitutor): CallableDesc
|
|||||||
|
|
||||||
fun CallableDescriptor.substituteAndApproximateTypes(
|
fun CallableDescriptor.substituteAndApproximateTypes(
|
||||||
substitutor: NewTypeSubstitutor,
|
substitutor: NewTypeSubstitutor,
|
||||||
typeApproximator: TypeApproximator
|
typeApproximator: TypeApproximator?
|
||||||
): CallableDescriptor {
|
): CallableDescriptor {
|
||||||
val wrappedSubstitution = object : TypeSubstitution() {
|
val wrappedSubstitution = object : TypeSubstitution() {
|
||||||
override fun get(key: KotlinType): TypeProjection? = null
|
override fun get(key: KotlinType): TypeProjection? = null
|
||||||
|
|
||||||
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) =
|
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) =
|
||||||
substitutor.safeSubstitute(topLevelType.unwrap()).let { substitutedType ->
|
substitutor.safeSubstitute(topLevelType.unwrap()).let { substitutedType ->
|
||||||
typeApproximator.approximateToSuperType(
|
typeApproximator?.approximateToSuperType(
|
||||||
substitutedType,
|
substitutedType,
|
||||||
TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
|
TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
|
||||||
) ?: substitutedType
|
) ?: substitutedType
|
||||||
|
|||||||
Reference in New Issue
Block a user