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.DescriptorUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.OverridingUtil;
|
import org.jetbrains.jet.lang.resolve.OverridingUtil;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace;
|
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.JetType;
|
||||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||||
@@ -69,16 +70,38 @@ public class OverloadingConflictResolver {
|
|||||||
boolean discriminateGenericDescriptors
|
boolean discriminateGenericDescriptors
|
||||||
) {
|
) {
|
||||||
D me = candidateCall.getResultingDescriptor();
|
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) {
|
for (ResolvedCallWithTrace<D> otherCall : candidates) {
|
||||||
D other = otherCall.getResultingDescriptor();
|
D other = otherCall.getResultingDescriptor();
|
||||||
if (other == me) continue;
|
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;
|
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"
|
* Let < mean "more specific"
|
||||||
* Subtype < supertype
|
* 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");
|
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() {
|
public static Test innerSuite() {
|
||||||
|
|||||||
Reference in New Issue
Block a user