diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java index b56de34cdd6..01409261f8f 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java @@ -1884,6 +1884,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte runTest("compiler/testData/diagnostics/tests/callableReference/memberExtensionsImportedFromObjectsUnsupported.kt"); } + @TestMetadata("noAmbiguityWhenAllReferencesAreInapplicable.kt") + public void testNoAmbiguityWhenAllReferencesAreInapplicable() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/noAmbiguityWhenAllReferencesAreInapplicable.kt"); + } + @TestMetadata("noExceptionOnRedCodeWithArrayLikeCall.kt") public void testNoExceptionOnRedCodeWithArrayLikeCall() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/noExceptionOnRedCodeWithArrayLikeCall.kt"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt index 061657ae761..549dce4fc2a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt @@ -148,7 +148,7 @@ class DiagnosticReporterByTrackingStrategy( val expression = ambiguityDiagnostic.argument.psiExpression.safeAs() val candidates = ambiguityDiagnostic.candidates.map { it.candidate } reportIfNonNull(expression) { - trace.report(CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY.on(it.callableReference, candidates)) + trace.reportDiagnosticOnce(CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY.on(it.callableReference, candidates)) trace.record(BindingContext.AMBIGUOUS_REFERENCE_TARGET, it.callableReference, candidates) } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt index 3d67048d6e0..c2aef4f7b85 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.resolve.calls.results.PlatformOverloadsSpecificityCo import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower import org.jetbrains.kotlin.resolve.calls.tower.TowerResolver +import org.jetbrains.kotlin.resolve.calls.tower.isInapplicable import org.jetbrains.kotlin.types.UnwrappedType @@ -79,6 +80,10 @@ class CallableReferenceResolver( } if (candidates.size > 1 && resolvedAtom is EagerCallableReferenceAtom) { + if (candidates.all { it.resultingApplicability.isInapplicable }) { + diagnosticsHolder.addDiagnostic(CallableReferenceCandidatesAmbiguity(argument, candidates)) + } + resolvedAtom.setAnalyzedResults( candidate = null, subResolvedAtoms = listOf(resolvedAtom.transformToPostponed()) diff --git a/compiler/testData/diagnostics/tests/callableReference/noAmbiguityWhenAllReferencesAreInapplicable.fir.kt b/compiler/testData/diagnostics/tests/callableReference/noAmbiguityWhenAllReferencesAreInapplicable.fir.kt new file mode 100644 index 00000000000..20a66918169 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/noAmbiguityWhenAllReferencesAreInapplicable.fir.kt @@ -0,0 +1,20 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE +// !LANGUAGE: +NewInference + +import kotlin.reflect.KFunction1 +import kotlin.reflect.KFunction2 + +object Foo { + fun bar(fn: KFunction1): String = "" + fun bar(fn: KFunction2): Int = 10 +} + +class A +class B + +fun A.test() = true // everything is OK without this line +fun B.test() = true + +fun main() { + val x = Foo.bar(B::test) // ambiguity in NI +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/callableReference/noAmbiguityWhenAllReferencesAreInapplicable.kt b/compiler/testData/diagnostics/tests/callableReference/noAmbiguityWhenAllReferencesAreInapplicable.kt new file mode 100644 index 00000000000..20a66918169 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/noAmbiguityWhenAllReferencesAreInapplicable.kt @@ -0,0 +1,20 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE +// !LANGUAGE: +NewInference + +import kotlin.reflect.KFunction1 +import kotlin.reflect.KFunction2 + +object Foo { + fun bar(fn: KFunction1): String = "" + fun bar(fn: KFunction2): Int = 10 +} + +class A +class B + +fun A.test() = true // everything is OK without this line +fun B.test() = true + +fun main() { + val x = Foo.bar(B::test) // ambiguity in NI +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/callableReference/noAmbiguityWhenAllReferencesAreInapplicable.txt b/compiler/testData/diagnostics/tests/callableReference/noAmbiguityWhenAllReferencesAreInapplicable.txt new file mode 100644 index 00000000000..d7aae7a2457 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/noAmbiguityWhenAllReferencesAreInapplicable.txt @@ -0,0 +1,28 @@ +package + +public fun main(): kotlin.Unit +public fun A.test(): kotlin.Boolean +public fun B.test(): kotlin.Boolean + +public final class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class B { + public constructor B() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public object Foo { + private constructor Foo() + public final fun bar(/*0*/ fn: kotlin.reflect.KFunction1): kotlin.String + public final fun bar(/*0*/ fn: kotlin.reflect.KFunction2): kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/multipleOutersAndMultipleCallableReferences.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/multipleOutersAndMultipleCallableReferences.kt index 747a2ca2cad..4ee3798be78 100644 --- a/compiler/testData/diagnostics/tests/callableReference/resolve/multipleOutersAndMultipleCallableReferences.kt +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/multipleOutersAndMultipleCallableReferences.kt @@ -12,5 +12,5 @@ fun bar(f: (T) -> Inv, p: String = "") {} fun bar(f: (T) -> Inv, p: Int = 4) {} fun test() { - bar(::foo) + bar(::foo) } \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 2af94d7c859..987d681d40b 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -1891,6 +1891,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/callableReference/memberExtensionsImportedFromObjectsUnsupported.kt"); } + @TestMetadata("noAmbiguityWhenAllReferencesAreInapplicable.kt") + public void testNoAmbiguityWhenAllReferencesAreInapplicable() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/noAmbiguityWhenAllReferencesAreInapplicable.kt"); + } + @TestMetadata("noExceptionOnRedCodeWithArrayLikeCall.kt") public void testNoExceptionOnRedCodeWithArrayLikeCall() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/noExceptionOnRedCodeWithArrayLikeCall.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 1b12c5f58e9..7e9f103bbcc 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -1886,6 +1886,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/callableReference/memberExtensionsImportedFromObjectsUnsupported.kt"); } + @TestMetadata("noAmbiguityWhenAllReferencesAreInapplicable.kt") + public void testNoAmbiguityWhenAllReferencesAreInapplicable() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/noAmbiguityWhenAllReferencesAreInapplicable.kt"); + } + @TestMetadata("noExceptionOnRedCodeWithArrayLikeCall.kt") public void testNoExceptionOnRedCodeWithArrayLikeCall() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/noExceptionOnRedCodeWithArrayLikeCall.kt");