From bfb13803d5e00d7493a19aace3c7a45825bd9902 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Fri, 19 Apr 2019 14:29:05 +0300 Subject: [PATCH] [NI] Fix reporting of overload resolution ambiguity --- .../resolve/calls/tower/PSICallResolver.kt | 21 ++++++++++--------- .../kotlin/resolve/calls/util/callUtil.kt | 7 +++++-- .../ExpectedParametersTypesMismatch.kt | 2 +- .../incompleteCode/unresolvedArguments.kt | 4 ++-- .../inference/recursiveLocalFuns/selfCall.kt | 2 +- .../tests/recovery/absentLeftHandSide.kt | 2 +- .../testData/diagnostics/tests/when/When.kt | 2 +- .../testsWithStdLib/addAllProjection.kt | 4 ++-- 8 files changed, 24 insertions(+), 20 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt index 2c30113d12c..49846d8ea2d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt @@ -20,14 +20,12 @@ import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver import org.jetbrains.kotlin.resolve.calls.CallTransformer import org.jetbrains.kotlin.resolve.calls.KotlinCallResolver import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isBinaryRemOperator -import org.jetbrains.kotlin.resolve.calls.callUtil.createLookupLocation -import org.jetbrains.kotlin.resolve.calls.callUtil.getCall -import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny -import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall +import org.jetbrains.kotlin.resolve.calls.callUtil.* import org.jetbrains.kotlin.resolve.calls.components.CallableReferenceResolver import org.jetbrains.kotlin.resolve.calls.components.InferenceSession import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext +import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode import org.jetbrains.kotlin.resolve.calls.context.ContextDependency import org.jetbrains.kotlin.resolve.calls.inference.buildResultingSubstitutor import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter @@ -232,7 +230,7 @@ class PSICallResolver( } diagnostics.firstIsInstanceOrNull()?.let { - return transformManyCandidatesAndRecordTrace(it, tracingStrategy, trace) + return transformManyCandidatesAndRecordTrace(it, tracingStrategy, trace, context) } if (getResultApplicability(diagnostics) == ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER) { @@ -250,7 +248,8 @@ class PSICallResolver( private fun transformManyCandidatesAndRecordTrace( diagnostic: ManyCandidatesCallDiagnostic, tracingStrategy: TracingStrategy, - trace: BindingTrace + trace: BindingTrace, + context: BasicCallResolutionContext ): ManyCandidates { val resolvedCalls = diagnostic.candidates.map { kotlinToResolvedCallTransformer.onlyTransform( @@ -267,10 +266,10 @@ class PSICallResolver( } } else { tracingStrategy.recordAmbiguity(trace, resolvedCalls) - if (resolvedCalls.first().status == ResolutionStatus.INCOMPLETE_TYPE_INFERENCE) { - tracingStrategy.cannotCompleteResolve(trace, resolvedCalls) - } else { - if (!resolvedCalls.all { it.isNewNotCompleted() }) { + if (!context.call.hasUnresolvedArguments(context)) { + if (resolvedCalls.allIncomplete) { + tracingStrategy.cannotCompleteResolve(trace, resolvedCalls) + } else { tracingStrategy.ambiguity(trace, resolvedCalls) } } @@ -278,6 +277,8 @@ class PSICallResolver( return ManyCandidates(resolvedCalls) } + private val List>.allIncomplete: Boolean get() = all { it.status == ResolutionStatus.INCOMPLETE_TYPE_INFERENCE } + private fun ResolvedCall<*>.recordEffects(trace: BindingTrace) { val moduleDescriptor = DescriptorUtils.getContainingModule(this.resultingDescriptor?.containingDeclaration ?: return) recordLambdasInvocations(trace, moduleDescriptor) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/callUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/callUtil.kt index 3cf33c6d90d..6927e4cf678 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/callUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/callUtil.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver import org.jetbrains.kotlin.resolve.calls.CallTransformer import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext import org.jetbrains.kotlin.resolve.calls.model.* +import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.isError @@ -78,8 +79,10 @@ fun > Call.hasUnresolvedArguments(context: ResolutionCo return arguments.any(fun(argument: KtExpression?): Boolean { if (argument == null || ArgumentTypeResolver.isFunctionLiteralOrCallableReference(argument, context)) return false - val resolvedCall = argument.getResolvedCall(context.trace.bindingContext) as MutableResolvedCall<*>? - if (resolvedCall != null && !resolvedCall.hasInferredReturnType()) return false + when (val resolvedCall = argument.getResolvedCall(context.trace.bindingContext)) { + is MutableResolvedCall<*> -> if (!resolvedCall.hasInferredReturnType()) return false + is NewResolvedCallImpl<*> -> if (resolvedCall.resultingDescriptor.returnType?.isError == true) return false + } val expressionType = context.trace.bindingContext.getType(argument) return expressionType == null || expressionType.isError diff --git a/compiler/testData/diagnostics/tests/functionLiterals/ExpectedParametersTypesMismatch.kt b/compiler/testData/diagnostics/tests/functionLiterals/ExpectedParametersTypesMismatch.kt index 8e41ca760af..cc3dc836f84 100644 --- a/compiler/testData/diagnostics/tests/functionLiterals/ExpectedParametersTypesMismatch.kt +++ b/compiler/testData/diagnostics/tests/functionLiterals/ExpectedParametersTypesMismatch.kt @@ -13,7 +13,7 @@ fun test1() { s: String-> "" } foo0 { - x, y -> "" + x, y -> "" } foo1 { diff --git a/compiler/testData/diagnostics/tests/incompleteCode/unresolvedArguments.kt b/compiler/testData/diagnostics/tests/incompleteCode/unresolvedArguments.kt index 50d41b75596..4a75d5f5fd9 100644 --- a/compiler/testData/diagnostics/tests/incompleteCode/unresolvedArguments.kt +++ b/compiler/testData/diagnostics/tests/incompleteCode/unresolvedArguments.kt @@ -8,6 +8,6 @@ fun bar(i: Int) {} fun bar(s: String) {} fun test() { - foo(rrr, 1) - bar(rrr) + foo(rrr, 1) + bar(rrr) } diff --git a/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/selfCall.kt b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/selfCall.kt index b06b0bbe2f0..82dcf83876b 100644 --- a/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/selfCall.kt +++ b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/selfCall.kt @@ -2,7 +2,7 @@ fun foo() { fun bar1() = bar1() - fun bar2() = 1 + bar2() + fun bar2() = 1 + bar2() fun bar3() = id(bar3()) } diff --git a/compiler/testData/diagnostics/tests/recovery/absentLeftHandSide.kt b/compiler/testData/diagnostics/tests/recovery/absentLeftHandSide.kt index 9f7d93ffd66..0d9a2300de3 100644 --- a/compiler/testData/diagnostics/tests/recovery/absentLeftHandSide.kt +++ b/compiler/testData/diagnostics/tests/recovery/absentLeftHandSide.kt @@ -4,7 +4,7 @@ fun import() { } fun composite() { - val s = 13+~/12 + val s = 13+~/12 } fun html() { diff --git a/compiler/testData/diagnostics/tests/when/When.kt b/compiler/testData/diagnostics/tests/when/When.kt index 67d028da910..dd05a58070e 100644 --- a/compiler/testData/diagnostics/tests/when/When.kt +++ b/compiler/testData/diagnostics/tests/when/When.kt @@ -11,7 +11,7 @@ fun foo() : Int { is Any -> 1 s -> 1 1 -> 1 - 1 + a -> 1 + 1 + a -> 1 in 1..a -> 1 !in 1..a -> 1 else -> 1 diff --git a/compiler/testData/diagnostics/testsWithStdLib/addAllProjection.kt b/compiler/testData/diagnostics/testsWithStdLib/addAllProjection.kt index 174883622d5..471fbbc25ce 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/addAllProjection.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/addAllProjection.kt @@ -4,12 +4,12 @@ fun test(mc: MutableCollection) { mc.addAll(mc) mc.addAll(arrayListOf()) - mc.addAll(arrayListOf()) + mc.addAll(arrayListOf()) mc.addAll(listOf("")) mc.addAll(listOf("")) mc.addAll(listOf("")) - mc.addAll(emptyList()) + mc.addAll(emptyList()) mc.addAll(emptyList()) }