diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index c6321f66dfd..5bdc9fa4d6e 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -11079,6 +11079,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/thisWithReceiverLabelsProperties.kt"); } + @Test + @TestMetadata("twoReceiverCandidatesError.kt") + public void testTwoReceiverCandidatesError() throws Exception { + runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/twoReceiverCandidatesError.kt"); + } + @Test @TestMetadata("typeParameterAsContextReceiver.kt") public void testTypeParameterAsContextReceiver() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 9cfc3ba2dd4..99f3c860255 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -11079,6 +11079,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/thisWithReceiverLabelsProperties.kt"); } + @Test + @TestMetadata("twoReceiverCandidatesError.kt") + public void testTwoReceiverCandidatesError() throws Exception { + runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/twoReceiverCandidatesError.kt"); + } + @Test @TestMetadata("typeParameterAsContextReceiver.kt") public void testTypeParameterAsContextReceiver() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 75b48de4a48..290b280e1af 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -11079,6 +11079,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/thisWithReceiverLabelsProperties.kt"); } + @Test + @TestMetadata("twoReceiverCandidatesError.kt") + public void testTwoReceiverCandidatesError() throws Exception { + runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/twoReceiverCandidatesError.kt"); + } + @Test @TestMetadata("typeParameterAsContextReceiver.kt") public void testTypeParameterAsContextReceiver() throws Exception { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt index 7d6c0c57679..3d67f9f741a 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt @@ -704,7 +704,10 @@ internal object CheckReceivers : ResolutionPart() { val extensionReceiverParameter = candidateDescriptor.extensionReceiverParameter ?: return null val compatible = receiverCandidates.mapNotNull { getReceiverArgumentWithConstraintIfCompatible(it, extensionReceiverParameter) } return when (compatible.size) { - 0 -> null + 0 -> { + addDiagnostic(NoMatchingContextReceiver()) + null + } 1 -> compatible.single().argument else -> { addDiagnostic(ContextReceiverAmbiguity()) @@ -954,4 +957,4 @@ internal object CheckIncompatibleTypeVariableUpperBounds : ResolutionPart() { } } } -} \ No newline at end of file +} diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ImplicitScopeTower.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ImplicitScopeTower.kt index 0aa188338e2..4d595fe0b89 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ImplicitScopeTower.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ImplicitScopeTower.kt @@ -114,6 +114,12 @@ abstract class ResolutionDiagnostic(candidateApplicability: CandidateApplicabili } } +class NoMatchingContextReceiver : ResolutionDiagnostic(INAPPLICABLE_WRONG_RECEIVER) { + override fun report(reporter: DiagnosticReporter) { + reporter.onCall(this) + } +} + class ContextReceiverAmbiguity : ResolutionDiagnostic(RESOLVED_WITH_ERROR) { override fun report(reporter: DiagnosticReporter) { reporter.onCall(this) diff --git a/compiler/testData/diagnostics/tests/extensions/contextReceivers/twoReceiverCandidatesError.kt b/compiler/testData/diagnostics/tests/extensions/contextReceivers/twoReceiverCandidatesError.kt new file mode 100644 index 00000000000..435652d136c --- /dev/null +++ b/compiler/testData/diagnostics/tests/extensions/contextReceivers/twoReceiverCandidatesError.kt @@ -0,0 +1,17 @@ +// !LANGUAGE: +ContextReceivers +// FIR_IDENTICAL + +fun String.foo() {} + +context(Int, Double) +fun bar() { + foo() // should be prohibited +} + +fun main() { + with(1) { + with(2.0) { + bar() + } + } +} diff --git a/compiler/testData/diagnostics/tests/extensions/contextReceivers/twoReceiverCandidatesError.txt b/compiler/testData/diagnostics/tests/extensions/contextReceivers/twoReceiverCandidatesError.txt new file mode 100644 index 00000000000..0d49c3d2f51 --- /dev/null +++ b/compiler/testData/diagnostics/tests/extensions/contextReceivers/twoReceiverCandidatesError.txt @@ -0,0 +1,5 @@ +package + +context(kotlin.Int, kotlin.Double) public fun bar(): kotlin.Unit +public fun main(): kotlin.Unit +public fun kotlin.String.foo(): kotlin.Unit diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 31ea410e471..9dc8d5042f6 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -11085,6 +11085,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/thisWithReceiverLabelsProperties.kt"); } + @Test + @TestMetadata("twoReceiverCandidatesError.kt") + public void testTwoReceiverCandidatesError() throws Exception { + runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/twoReceiverCandidatesError.kt"); + } + @Test @TestMetadata("typeParameterAsContextReceiver.kt") public void testTypeParameterAsContextReceiver() throws Exception {