[NI] Fix reporting of overload resolution ambiguity

This commit is contained in:
Dmitriy Novozhilov
2019-04-19 14:29:05 +03:00
parent f9cc3d9be3
commit bfb13803d5
8 changed files with 24 additions and 20 deletions
@@ -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<ManyCandidatesCallDiagnostic>()?.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 <D : CallableDescriptor> transformManyCandidatesAndRecordTrace(
diagnostic: ManyCandidatesCallDiagnostic,
tracingStrategy: TracingStrategy,
trace: BindingTrace
trace: BindingTrace,
context: BasicCallResolutionContext
): ManyCandidates<D> {
val resolvedCalls = diagnostic.candidates.map {
kotlinToResolvedCallTransformer.onlyTransform<D>(
@@ -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<ResolvedCall<*>>.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)
@@ -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 <C : ResolutionContext<C>> 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
@@ -13,7 +13,7 @@ fun test1() {
<!EXPECTED_PARAMETERS_NUMBER_MISMATCH!><!UNUSED_ANONYMOUS_PARAMETER!>s<!>: String<!>-> ""
}<!>
foo0 <!NI;TYPE_MISMATCH!>{
<!EXPECTED_PARAMETERS_NUMBER_MISMATCH!><!CANNOT_INFER_PARAMETER_TYPE, UNUSED_ANONYMOUS_PARAMETER!>x<!>, <!NI;CANNOT_INFER_PARAMETER_TYPE, OI;CANNOT_INFER_PARAMETER_TYPE, UNUSED_ANONYMOUS_PARAMETER!>y<!><!> -> ""
<!EXPECTED_PARAMETERS_NUMBER_MISMATCH!><!CANNOT_INFER_PARAMETER_TYPE, UNUSED_ANONYMOUS_PARAMETER!>x<!>, <!CANNOT_INFER_PARAMETER_TYPE, UNUSED_ANONYMOUS_PARAMETER!>y<!><!> -> ""
}<!>
foo1 {
@@ -8,6 +8,6 @@ fun bar(i: Int) {}
fun bar(s: String) {}
fun test() {
<!NI;OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>(<!UNRESOLVED_REFERENCE!>rrr<!>, 1)
<!NI;OVERLOAD_RESOLUTION_AMBIGUITY!>bar<!>(<!UNRESOLVED_REFERENCE!>rrr<!>)
foo(<!UNRESOLVED_REFERENCE!>rrr<!>, 1)
bar(<!UNRESOLVED_REFERENCE!>rrr<!>)
}
@@ -2,7 +2,7 @@
fun foo() {
fun bar1() = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!><!NI;DEBUG_INFO_MISSING_UNRESOLVED!>bar1<!>()<!>
fun bar2() = 1 <!NI;OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!><!NI;DEBUG_INFO_MISSING_UNRESOLVED!>bar2<!>()<!>
fun bar2() = 1 + <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!><!NI;DEBUG_INFO_MISSING_UNRESOLVED!>bar2<!>()<!>
fun <!NI;IMPLICIT_NOTHING_RETURN_TYPE!>bar3<!>() = <!NI;IMPLICIT_NOTHING_AS_TYPE_PARAMETER!>id<!>(<!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!><!NI;DEBUG_INFO_MISSING_UNRESOLVED!>bar3<!>()<!>)
}
@@ -4,7 +4,7 @@ fun import() {
}
fun composite() {
val <!UNUSED_VARIABLE!>s<!> = 13<!NI;OVERLOAD_RESOLUTION_AMBIGUITY!>+<!><!SYNTAX!>~<!><!DEBUG_INFO_MISSING_UNRESOLVED!>/<!>12
val <!UNUSED_VARIABLE!>s<!> = 13+<!SYNTAX!>~<!><!DEBUG_INFO_MISSING_UNRESOLVED!>/<!>12
}
fun html() {
+1 -1
View File
@@ -11,7 +11,7 @@ fun foo() : Int {
<!USELESS_IS_CHECK!>is Any<!> -> <!UNUSED_EXPRESSION!>1<!>
<!INCOMPATIBLE_TYPES!>s<!> -> <!UNUSED_EXPRESSION!>1<!>
1 -> <!UNUSED_EXPRESSION!>1<!>
1 <!NI;OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>a<!> -> <!UNUSED_EXPRESSION!>1<!>
1 + <!UNRESOLVED_REFERENCE!>a<!> -> <!UNUSED_EXPRESSION!>1<!>
in 1..<!UNRESOLVED_REFERENCE!>a<!> -> <!UNUSED_EXPRESSION!>1<!>
!in 1..<!UNRESOLVED_REFERENCE!>a<!> -> <!UNUSED_EXPRESSION!>1<!>
else -> <!UNUSED_EXPRESSION!>1<!>
@@ -4,12 +4,12 @@ fun test(mc: MutableCollection<out CharSequence>) {
mc.addAll(<!TYPE_MISMATCH_DUE_TO_TYPE_PROJECTIONS!>mc<!>)
mc.addAll(<!TYPE_MISMATCH_DUE_TO_TYPE_PROJECTIONS!>arrayListOf<CharSequence>()<!>)
mc.addAll(<!NI;IMPLICIT_NOTHING_AS_TYPE_PARAMETER, IMPLICIT_NOTHING_AS_TYPE_PARAMETER!>arrayListOf<!>())
mc.addAll(<!IMPLICIT_NOTHING_AS_TYPE_PARAMETER, NI;IMPLICIT_NOTHING_AS_TYPE_PARAMETER!>arrayListOf<!>())
mc.addAll(<!TYPE_MISMATCH_DUE_TO_TYPE_PROJECTIONS!>listOf("")<!>)
mc.addAll(<!TYPE_MISMATCH_DUE_TO_TYPE_PROJECTIONS!>listOf<String>("")<!>)
mc.addAll(<!NI;TYPE_MISMATCH, TYPE_MISMATCH_DUE_TO_TYPE_PROJECTIONS!>listOf<CharSequence>("")<!>)
mc.addAll(<!NI;IMPLICIT_NOTHING_AS_TYPE_PARAMETER, IMPLICIT_NOTHING_AS_TYPE_PARAMETER!>emptyList<!>())
mc.addAll(<!IMPLICIT_NOTHING_AS_TYPE_PARAMETER, NI;IMPLICIT_NOTHING_AS_TYPE_PARAMETER!>emptyList<!>())
mc.addAll(emptyList<Nothing>())
}