KT-3772 Invoke and overload resolution ambiguity

#KT-3772 Fixed
This commit is contained in:
Svetlana Isakova
2013-07-16 20:18:33 +04:00
parent 3f782523a7
commit 539756ff3e
3 changed files with 55 additions and 2 deletions
@@ -24,6 +24,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.OverridingUtil;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace;
import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
@@ -69,16 +70,38 @@ public class OverloadingConflictResolver {
boolean discriminateGenericDescriptors
) {
D me = candidateCall.getResultingDescriptor();
boolean isInvoke = candidateCall instanceof VariableAsFunctionResolvedCall;
VariableDescriptor variable;
if (isInvoke) {
variable = ((VariableAsFunctionResolvedCall) candidateCall).getVariableCall().getResultingDescriptor();
}
else {
variable = null;
}
for (ResolvedCallWithTrace<D> otherCall : candidates) {
D other = otherCall.getResultingDescriptor();
if (other == me) continue;
if (!moreSpecific(me, other, discriminateGenericDescriptors) || moreSpecific(other, me, discriminateGenericDescriptors)) {
return false;
if (definitelyNotMaximallySpecific(me, other, discriminateGenericDescriptors)) {
if (!isInvoke) return false;
assert otherCall instanceof VariableAsFunctionResolvedCall : "'invoke' candidate goes with usual one: " + candidateCall + otherCall;
ResolvedCallWithTrace<VariableDescriptor> otherVariableCall = ((VariableAsFunctionResolvedCall) otherCall).getVariableCall();
if (definitelyNotMaximallySpecific(variable, otherVariableCall.getResultingDescriptor(), discriminateGenericDescriptors)) {
return false;
}
}
}
return true;
}
private <D extends CallableDescriptor> boolean definitelyNotMaximallySpecific(D me, D other, boolean discriminateGenericDescriptors) {
return !moreSpecific(me, other, discriminateGenericDescriptors) || moreSpecific(other, me, discriminateGenericDescriptors);
}
/**
* Let < mean "more specific"
* Subtype < supertype
@@ -0,0 +1,25 @@
//KT-3772 Invoke and overload resolution ambiguity
package bar
open class A {
public fun invoke(<!UNUSED_PARAMETER!>f<!>: A.() -> Unit) {}
}
class B {
public fun invoke(<!UNUSED_PARAMETER!>f<!>: B.() -> Unit) {}
}
open class C
val C.attr = A()
open class D: C()
val D.attr = B()
fun main(args: Array<String>) {
val b = D()
b.attr {} // overload resolution ambiguity
val d = b.attr
d {} // no error
}
@@ -4582,6 +4582,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
doTest("compiler/testData/diagnostics/tests/resolve/invoke/invokeAsMemberExtensionToExplicitReceiver.kt");
}
@TestMetadata("kt3772.kt")
public void testKt3772() throws Exception {
doTest("compiler/testData/diagnostics/tests/resolve/invoke/kt3772.kt");
}
}
public static Test innerSuite() {