From 7ace303addafa0a198fe676688f6905376c9a5d7 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 27 Oct 2017 19:27:12 +0200 Subject: [PATCH] Fix ambiguity on callable reference for expect members Expect members should always lose in resolution to non-expect members, be it simple calls or callable references. Note that there should be exactly one actual member for each expect member in correct code, so both ways to check for expect vs non-expect are correct: either before signature comparison, or after. #KT-20903 Fixed --- .../results/OverloadingConflictResolver.kt | 11 +++++++++- .../callableReferenceOnExpectFun.kt | 21 +++++++++++++++++++ .../callableReferenceOnExpectFun.txt | 18 ++++++++++++++++ .../checkers/DiagnosticsTestGenerated.java | 6 ++++++ .../DiagnosticsUsingJavacTestGenerated.java | 6 ++++++ 5 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/diagnostics/tests/multiplatform/topLevelFun/callableReferenceOnExpectFun.kt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/topLevelFun/callableReferenceOnExpectFun.txt diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/OverloadingConflictResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/OverloadingConflictResolver.kt index c2d35477487..a46d3c53e63 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/OverloadingConflictResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/OverloadingConflictResolver.kt @@ -352,7 +352,16 @@ open class OverloadingConflictResolver( val fSignature = FlatSignature.createFromCallableDescriptor(f) val gSignature = FlatSignature.createFromCallableDescriptor(g) - return createEmptyConstraintSystem().isSignatureNotLessSpecific(fSignature, gSignature, SpecificityComparisonWithNumerics, specificityComparator) + if (!createEmptyConstraintSystem().isSignatureNotLessSpecific(fSignature, gSignature, SpecificityComparisonWithNumerics, specificityComparator)) { + return false + } + + if (f is CallableMemberDescriptor && g is CallableMemberDescriptor) { + if (!f.isExpect && g.isExpect) return true + if (f.isExpect && !g.isExpect) return false + } + + return true } private fun isNotLessSpecificCallableReference(f: CallableDescriptor, g: CallableDescriptor): Boolean = diff --git a/compiler/testData/diagnostics/tests/multiplatform/topLevelFun/callableReferenceOnExpectFun.kt b/compiler/testData/diagnostics/tests/multiplatform/topLevelFun/callableReferenceOnExpectFun.kt new file mode 100644 index 00000000000..0c22e4752ef --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/topLevelFun/callableReferenceOnExpectFun.kt @@ -0,0 +1,21 @@ +// !LANGUAGE: +MultiPlatformProjects +// MODULE: m1-common +// FILE: common.kt + +package test + +expect fun foo(): String + +fun g(f: () -> String): String = f() + +fun test() { + g(::foo) +} + +// MODULE: m2-jvm(m1-common) +// FILE: jvm.kt + +package test + +@Deprecated("To check that ::foo is resolved to actual fun foo when compiling common+jvm") +actual fun foo(): String = "" diff --git a/compiler/testData/diagnostics/tests/multiplatform/topLevelFun/callableReferenceOnExpectFun.txt b/compiler/testData/diagnostics/tests/multiplatform/topLevelFun/callableReferenceOnExpectFun.txt new file mode 100644 index 00000000000..aae2194d48b --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/topLevelFun/callableReferenceOnExpectFun.txt @@ -0,0 +1,18 @@ +// -- Module: -- +package + +package test { + public expect fun foo(): kotlin.String + public fun g(/*0*/ f: () -> kotlin.String): kotlin.String + public fun test(): kotlin.Unit +} + + +// -- Module: -- +package + +package test { + @kotlin.Deprecated(message = "To check that ::foo is resolved to actual fun foo when compiling common+jvm") public actual fun foo(): kotlin.String + public fun g(/*0*/ f: () -> kotlin.String): kotlin.String + public fun test(): kotlin.Unit +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index e0855333057..06a99df96b1 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -14355,6 +14355,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("callableReferenceOnExpectFun.kt") + public void testCallableReferenceOnExpectFun() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/topLevelFun/callableReferenceOnExpectFun.kt"); + doTest(fileName); + } + @TestMetadata("conflictingHeaderDeclarations.kt") public void testConflictingHeaderDeclarations() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/topLevelFun/conflictingHeaderDeclarations.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index a1d041b2af2..306adad4127 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -14355,6 +14355,12 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing doTest(fileName); } + @TestMetadata("callableReferenceOnExpectFun.kt") + public void testCallableReferenceOnExpectFun() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/topLevelFun/callableReferenceOnExpectFun.kt"); + doTest(fileName); + } + @TestMetadata("conflictingHeaderDeclarations.kt") public void testConflictingHeaderDeclarations() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/topLevelFun/conflictingHeaderDeclarations.kt");