KT-3772 Invoke and overload resolution ambiguity
#KT-3772 Fixed
This commit is contained in:
+25
-2
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user