diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 8b56bc98933..7efe975c324 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -759,6 +759,8 @@ public interface Errors { DiagnosticFactory1 TYPE_PARAMETER_AS_REIFIED_ARRAY_WARNING = DiagnosticFactory1.create(WARNING); DiagnosticFactory1 REIFIED_TYPE_FORBIDDEN_SUBSTITUTION = DiagnosticFactory1.create(ERROR); DiagnosticFactory1 REIFIED_TYPE_UNSAFE_SUBSTITUTION = DiagnosticFactory1.create(WARNING); + DiagnosticFactory0 CANDIDATE_CHOSEN_USING_OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION = DiagnosticFactory0.create(WARNING); + DiagnosticFactory3 RESOLUTION_TO_CLASSIFIER = DiagnosticFactory3.create(ERROR); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index c5c8c113eb3..6701fab2edf 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -896,6 +896,7 @@ public class DefaultErrorMessages { MAP.put(REIFIED_TYPE_FORBIDDEN_SUBSTITUTION, "Cannot use ''{0}'' as reified type parameter", RENDER_TYPE); MAP.put(REIFIED_TYPE_UNSAFE_SUBSTITUTION, "It may be not safe to use ''{0}'' as an argument for a reified type parameter. Use a non-generic type or * if possible", RENDER_TYPE); MAP.put(TYPE_PARAMETERS_NOT_ALLOWED, "Type parameters are not allowed here"); + MAP.put(CANDIDATE_CHOSEN_USING_OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION, "Candidate was choosen only by @OverloadResolutionByLambdaReturnType annotation"); MAP.put(TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER, "Type parameter of a property must be used in its receiver type"); 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 65fc1ec6b02..ab0e80c5bf6 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt @@ -77,6 +77,9 @@ class DiagnosticReporterByTrackingStrategy( trace.report(factory.on(it, typeVariable.originalTypeParameter)) } } + CandidateChosenUsingOverloadResolutionByLambdaAnnotation::class.java -> { + trace.report(CANDIDATE_CHOSEN_USING_OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION.on(psiKotlinCall.psiCall.callElement)) + } } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinCallResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinCallResolver.kt index ca07f9d8776..f40ca24c11f 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinCallResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinCallResolver.kt @@ -155,6 +155,7 @@ class KotlinCallResolver( if (maximallySpecificCandidates.size > 1) { maximallySpecificCandidates = candidates.toMutableSet().apply { removeAll(candidatesWithAnnotation) } + maximallySpecificCandidates.singleOrNull()?.addDiagnostic(CandidateChosenUsingOverloadResolutionByLambdaAnnotation()) } } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt index 01a824982f8..48876cf5fe5 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt @@ -243,3 +243,9 @@ class NotEnoughInformationForLambdaParameter( reporter.onCallArgument(lambdaArgument, this) } } + +class CandidateChosenUsingOverloadResolutionByLambdaAnnotation : KotlinCallDiagnostic(RESOLVED) { + override fun report(reporter: DiagnosticReporter) { + reporter.onCall(this) + } +} diff --git a/compiler/testData/codegen/box/ranges/unsigned/literal/simpleRange.kt b/compiler/testData/codegen/box/ranges/unsigned/literal/simpleRange.kt index 7538c5a1630..13d0ce94d21 100644 --- a/compiler/testData/codegen/box/ranges/unsigned/literal/simpleRange.kt +++ b/compiler/testData/codegen/box/ranges/unsigned/literal/simpleRange.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND_FIR: JVM_IR // KJS_WITH_FULL_RUNTIME // Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! // WITH_RUNTIME diff --git a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.fir.kt index 01eb419bfe6..869cf15f35d 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.fir.kt @@ -45,4 +45,17 @@ fun test_4() { fun test_5() { val x = create("") { 1 } takeInt(x) -} \ No newline at end of file +} + +interface A +interface B +interface C : A, B + +@OverloadResolutionByLambdaReturnType +fun foo(f: () -> A): Int = 1 +fun foo(f: () -> B): String = "" + +fun test_6(c: C) { + val x = foo { c } + takeString(x) +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.kt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.kt index 3b4ccc2e7d5..eec692256a8 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.kt @@ -30,7 +30,7 @@ fun test_2() { } fun test_3() { - val x = create { 1.0 } + val x = create { 1.0 } } @OverloadResolutionByLambdaReturnType @@ -45,4 +45,17 @@ fun test_4() { fun test_5() { val x = create("") { 1 } takeInt(x) -} \ No newline at end of file +} + +interface A +interface B +interface C : A, B + +@OverloadResolutionByLambdaReturnType +fun foo(f: () -> A): Int = 1 +fun foo(f: () -> B): String = "" + +fun test_6(c: C) { + val x = foo { c } + takeString(x) +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.txt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.txt index db0cf51fe1e..e33c6ebe5be 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.txt @@ -4,6 +4,8 @@ package public fun create(/*0*/ f: (kotlin.Int) -> kotlin.String): kotlin.String @kotlin.OverloadResolutionByLambdaReturnType public fun create(/*0*/ x: K, /*1*/ f: (K) -> kotlin.Int): kotlin.Int public fun create(/*0*/ x: T, /*1*/ f: (T) -> kotlin.String): kotlin.String +@kotlin.OverloadResolutionByLambdaReturnType public fun foo(/*0*/ f: () -> A): kotlin.Int +public fun foo(/*0*/ f: () -> B): kotlin.String public fun takeInt(/*0*/ s: kotlin.Int): kotlin.Unit public fun takeString(/*0*/ s: kotlin.String): kotlin.Unit public fun test_1(): kotlin.Unit @@ -11,6 +13,25 @@ public fun test_2(): kotlin.Unit public fun test_3(): kotlin.Unit public fun test_4(): kotlin.Unit public fun test_5(): kotlin.Unit +public fun test_6(/*0*/ c: C): kotlin.Unit + +public interface 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 interface 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 interface C : A, B { + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} package kotlin {