Restore correct overloads ambiguity accidentally removed in 1.3.60

This problem is only relevant when isTypeRefinementEnabled == true (HMPP projects)

Ambiguity accidentally was removed after 471134d
There, for areCallableDescriptorsEquivalent we stopped assuming
as impossible a situation of having identity-different descriptors
in the same containing declaraton that still might be considered equal

So, before 471134d we were comparing
"fun foo(x: String)" with "[substituted] fun foo(x: String)"
and areCallableDescriptorsEquivalent returned false for such case.
Thus, both overrides were left in the resulting set.

After 471134d, those two descriptors
becamed considered as equal thus having a possibility to remove any of them.

The problem is that "areCallableDescriptorsEquivalent" has kind of
unclear contract. Effectively it checks whether two descriptors match
to the same declaration.

But some of the usages expect that it also makes sure that descriptors
have the same substitution (see org.jetbrains.kotlin.resolve.calls.smartcasts.IdentifierInfo.Variable#equals)

So, the straight solution is using original descriptors for the cases
where we need to make sure that descriptors relates to actually different
declarations

^KT-34027 Fixed
This commit is contained in:
Denis Zharkov
2019-09-30 17:18:43 +03:00
parent 67410f7a57
commit f91db5f0b8
10 changed files with 77 additions and 2 deletions
@@ -18088,6 +18088,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
runTest("compiler/testData/diagnostics/tests/resolve/overloadConflicts/extensionReceiverAndVarargs.kt");
}
@TestMetadata("genericClash.kt")
public void testGenericClash() throws Exception {
runTest("compiler/testData/diagnostics/tests/resolve/overloadConflicts/genericClash.kt");
}
@TestMetadata("genericWithProjection.kt")
public void testGenericWithProjection() throws Exception {
runTest("compiler/testData/diagnostics/tests/resolve/overloadConflicts/genericWithProjection.kt");
@@ -124,8 +124,8 @@ open class OverloadingConflictResolver<C : Any>(
val result = LinkedHashSet<C>()
outerLoop@ for (meD in fromSourcesGoesFirst) {
for (otherD in result) {
val me = meD.resultingDescriptor
val other = otherD.resultingDescriptor
val me = meD.resultingDescriptor.originalIfTypeRefinementEnabled
val other = otherD.resultingDescriptor.originalIfTypeRefinementEnabled
val ignoreReturnType = isFromSources(me) != isFromSources(other)
if (DescriptorEquivalenceForOverrides.areCallableDescriptorsEquivalent(
me,
@@ -143,6 +143,8 @@ open class OverloadingConflictResolver<C : Any>(
return result
}
private val CallableDescriptor.originalIfTypeRefinementEnabled get() = if (isTypeRefinementEnabled) original else this
private fun Collection<C>.setIfOneOrEmpty() = when (size) {
0 -> emptySet()
1 -> setOf(single())
@@ -0,0 +1,19 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
interface A<T> {
fun foo(x: T)
fun foo(x: String)
fun <E> baz(x: E, y: String)
fun <E> baz(x: String, y: E)
}
fun <E> baz(x: E, y: String) {}
fun <E> baz(x: String, y: E) {}
fun bar(x: A<String>) {
x.<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>("")
x.<!CANNOT_COMPLETE_RESOLVE!>baz<!>("", "")
<!CANNOT_COMPLETE_RESOLVE!>baz<!>("", "")
}
@@ -0,0 +1,15 @@
package
public fun bar(/*0*/ x: A<kotlin.String>): kotlin.Unit
public fun </*0*/ E> baz(/*0*/ x: E, /*1*/ y: kotlin.String): kotlin.Unit
public fun </*0*/ E> baz(/*0*/ x: kotlin.String, /*1*/ y: E): kotlin.Unit
public interface A</*0*/ T> {
public abstract fun </*0*/ E> baz(/*0*/ x: E, /*1*/ y: kotlin.String): kotlin.Unit
public abstract fun </*0*/ E> baz(/*0*/ x: kotlin.String, /*1*/ y: E): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(/*0*/ x: T): kotlin.Unit
public abstract fun foo(/*0*/ x: kotlin.String): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -18100,6 +18100,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
runTest("compiler/testData/diagnostics/tests/resolve/overloadConflicts/extensionReceiverAndVarargs.kt");
}
@TestMetadata("genericClash.kt")
public void testGenericClash() throws Exception {
runTest("compiler/testData/diagnostics/tests/resolve/overloadConflicts/genericClash.kt");
}
@TestMetadata("genericWithProjection.kt")
public void testGenericWithProjection() throws Exception {
runTest("compiler/testData/diagnostics/tests/resolve/overloadConflicts/genericWithProjection.kt");
@@ -18090,6 +18090,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/resolve/overloadConflicts/extensionReceiverAndVarargs.kt");
}
@TestMetadata("genericClash.kt")
public void testGenericClash() throws Exception {
runTest("compiler/testData/diagnostics/tests/resolve/overloadConflicts/genericClash.kt");
}
@TestMetadata("genericWithProjection.kt")
public void testGenericWithProjection() throws Exception {
runTest("compiler/testData/diagnostics/tests/resolve/overloadConflicts/genericWithProjection.kt");
@@ -0,0 +1,6 @@
// KT-34027
expect interface A<T> {
fun foo(x: T)
}
fun bar(): A<String> = null!!
@@ -0,0 +1,5 @@
MODULE common { platform=[JVM, JS, Native] }
MODULE js { platform=[JS] }
js -> common { kind=DEPENDS_ON }
@@ -0,0 +1,8 @@
actual interface A<T> {
actual fun foo(x: T)
fun foo(x: String)
}
fun main() {
bar().<!OVERLOAD_RESOLUTION_AMBIGUITY(" public abstract actual fun foo(x: String): Unit defined in A public abstract fun foo(x: String): Unit defined in A")!>foo<!>("")
}
@@ -44,6 +44,11 @@ public class MultiplatformAnalysisTestGenerated extends AbstractMultiplatformAna
runTest("idea/testData/multiplatform/constructorsOfExpect/");
}
@TestMetadata("correctOverloadResolutionAmbiguity")
public void testCorrectOverloadResolutionAmbiguity() throws Exception {
runTest("idea/testData/multiplatform/correctOverloadResolutionAmbiguity/");
}
@TestMetadata("diamondModuleDependency1")
public void testDiamondModuleDependency1() throws Exception {
runTest("idea/testData/multiplatform/diamondModuleDependency1/");