diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestWithStdlibGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestWithStdlibGenerated.java index 124f0f2f4b6..7d5f5a25bec 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestWithStdlibGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestWithStdlibGenerated.java @@ -1809,6 +1809,11 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi public void testOverloadByLambdaReturnType_enabled() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.kt"); } + + @TestMetadata("overloadByLambdaReturnType_enabled_no_annotation.kt") + public void testOverloadByLambdaReturnType_enabled_no_annotation() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled_no_annotation.kt"); + } } @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/forInArrayLoop") 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 f1dc80ee7ee..f0580a2eb1e 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinCallResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinCallResolver.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.resolve.calls import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus import org.jetbrains.kotlin.resolve.calls.components.* import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode @@ -36,6 +37,9 @@ class KotlinCallResolver( private val callableReferenceResolver: CallableReferenceResolver, private val callComponents: KotlinCallComponents ) { + companion object { + private val FACTORY_PATTERN_ANNOTATION = FqName.fromSegments(listOf("annotations", "FactoryPattern")) + } fun resolveCall( scopeTower: ImplicitScopeTower, @@ -147,13 +151,16 @@ class KotlinCallResolver( discriminateGenerics = true // todo ) - if (maximallySpecificCandidates.size > 1 && callComponents.languageVersionSettings.supportsFeature(LanguageFeature.FactoryPatternResolution)) { + if ( + maximallySpecificCandidates.size > 1 && + callComponents.languageVersionSettings.supportsFeature(LanguageFeature.FactoryPatternResolution) && + candidates.any { it.resolvedCall.candidateDescriptor.annotations.hasAnnotation(FACTORY_PATTERN_ANNOTATION) } && + candidates.all { resolutionCallbacks.inferenceSession.shouldRunCompletion(it) } + ) { maximallySpecificCandidates = kotlinCallCompleter.chooseCandidateRegardingFactoryPatternResolution(maximallySpecificCandidates, resolutionCallbacks) } return kotlinCallCompleter.runCompletion(candidateFactory, maximallySpecificCandidates, expectedType, resolutionCallbacks) } - - } diff --git a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.fir.kt index 177b751e59b..968ec7c2efb 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.fir.kt @@ -2,6 +2,17 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION // ISSUE: KT-11265 +// FILE: FactoryPattern.kt + +package annotations + +annotation class FactoryPattern + +// FILE: main.kt + +import annotations.FactoryPattern + +@FactoryPattern fun create(f: (Int) -> Int): Int = 1 fun create(f: (Int) -> String): String = "" @@ -22,6 +33,7 @@ fun test_3() { val x = create { 1.0 } } +@FactoryPattern fun create(x: K, f: (K) -> Int): Int = 1 fun create(x: T, f: (T) -> String): String = "" diff --git a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt index 0ae9029bbd7..dbef1ccfd4b 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt @@ -2,6 +2,17 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION // ISSUE: KT-11265 +// FILE: FactoryPattern.kt + +package annotations + +annotation class FactoryPattern + +// FILE: main.kt + +import annotations.FactoryPattern + +@FactoryPattern fun create(f: (Int) -> Int): Int = 1 fun create(f: (Int) -> String): String = "" @@ -22,6 +33,7 @@ fun test_3() { val x = create { 1.0 } } +@FactoryPattern fun create(x: K, f: (K) -> Int): Int = 1 fun create(x: T, f: (T) -> String): String = "" diff --git a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.txt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.txt index 0581aa1b7c8..fbc236fdd50 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.txt @@ -1,8 +1,8 @@ package -public fun create(/*0*/ f: (kotlin.Int) -> kotlin.Int): kotlin.Int +@annotations.FactoryPattern public fun create(/*0*/ f: (kotlin.Int) -> kotlin.Int): kotlin.Int public fun create(/*0*/ f: (kotlin.Int) -> kotlin.String): kotlin.String -public fun create(/*0*/ x: K, /*1*/ f: (K) -> kotlin.Int): kotlin.Int +@annotations.FactoryPattern 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 public fun takeInt(/*0*/ s: kotlin.Int): kotlin.Unit public fun takeString(/*0*/ s: kotlin.String): kotlin.Unit @@ -11,3 +11,13 @@ public fun test_2(): kotlin.Unit public fun test_3(): kotlin.Unit public fun test_4(): kotlin.Unit public fun test_5(): kotlin.Unit + +package annotations { + + public final annotation class FactoryPattern : kotlin.Annotation { + public constructor FactoryPattern() + 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/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.fir.kt index e3cde147844..dc277897d01 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.fir.kt @@ -2,6 +2,17 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION // ISSUE: KT-11265 +// FILE: FactoryPattern.kt + +package annotations + +annotation class FactoryPattern + +// FILE: main.kt + +import annotations.FactoryPattern + +@FactoryPattern fun create(f: (Int) -> Int): Int = 1 fun create(f: (Int) -> String): String = "" @@ -22,6 +33,7 @@ fun test_3() { val x = create { 1.0 } } +@FactoryPattern fun create(x: K, f: (K) -> Int): Int = 1 fun create(x: T, f: (T) -> String): String = "" diff --git a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.kt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.kt index 0d13c22999e..327593eeefb 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.kt @@ -2,6 +2,17 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION // ISSUE: KT-11265 +// FILE: FactoryPattern.kt + +package annotations + +annotation class FactoryPattern + +// FILE: main.kt + +import annotations.FactoryPattern + +@FactoryPattern fun create(f: (Int) -> Int): Int = 1 fun create(f: (Int) -> String): String = "" @@ -22,6 +33,7 @@ fun test_3() { val x = create { 1.0 } } +@FactoryPattern fun create(x: K, f: (K) -> Int): Int = 1 fun create(x: T, f: (T) -> String): String = "" diff --git a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.txt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.txt index 0581aa1b7c8..fbc236fdd50 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.txt @@ -1,8 +1,8 @@ package -public fun create(/*0*/ f: (kotlin.Int) -> kotlin.Int): kotlin.Int +@annotations.FactoryPattern public fun create(/*0*/ f: (kotlin.Int) -> kotlin.Int): kotlin.Int public fun create(/*0*/ f: (kotlin.Int) -> kotlin.String): kotlin.String -public fun create(/*0*/ x: K, /*1*/ f: (K) -> kotlin.Int): kotlin.Int +@annotations.FactoryPattern 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 public fun takeInt(/*0*/ s: kotlin.Int): kotlin.Unit public fun takeString(/*0*/ s: kotlin.String): kotlin.Unit @@ -11,3 +11,13 @@ public fun test_2(): kotlin.Unit public fun test_3(): kotlin.Unit public fun test_4(): kotlin.Unit public fun test_5(): kotlin.Unit + +package annotations { + + public final annotation class FactoryPattern : kotlin.Annotation { + public constructor FactoryPattern() + 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/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled_no_annotation.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled_no_annotation.fir.kt new file mode 100644 index 00000000000..e3cde147844 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled_no_annotation.fir.kt @@ -0,0 +1,36 @@ +// !LANGUAGE: +NewInference +FactoryPatternResolution +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION +// ISSUE: KT-11265 + +fun create(f: (Int) -> Int): Int = 1 +fun create(f: (Int) -> String): String = "" + +fun takeString(s: String) {} +fun takeInt(s: Int) {} + +fun test_1() { + val x = create { "" } + takeString(x) +} + +fun test_2() { + val x = create { 1 } + takeInt(x) +} + +fun test_3() { + val x = create { 1.0 } +} + +fun create(x: K, f: (K) -> Int): Int = 1 +fun create(x: T, f: (T) -> String): String = "" + +fun test_4() { + val x = create("") { "" } + takeString(x) +} + +fun test_5() { + val x = create("") { 1 } + takeInt(x) +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled_no_annotation.kt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled_no_annotation.kt new file mode 100644 index 00000000000..7f924f1496a --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled_no_annotation.kt @@ -0,0 +1,36 @@ +// !LANGUAGE: +NewInference +FactoryPatternResolution +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION +// ISSUE: KT-11265 + +fun create(f: (Int) -> Int): Int = 1 +fun create(f: (Int) -> String): String = "" + +fun takeString(s: String) {} +fun takeInt(s: Int) {} + +fun test_1() { + val x = create { "" } + takeString(x) +} + +fun test_2() { + val x = create { 1 } + takeInt(x) +} + +fun test_3() { + val x = create { 1.0 } +} + +fun create(x: K, f: (K) -> Int): Int = 1 +fun create(x: T, f: (T) -> String): String = "" + +fun test_4() { + val x = create("") { "" } + takeString(x) +} + +fun test_5() { + val x = create("") { 1 } + takeInt(x) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled_no_annotation.txt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled_no_annotation.txt new file mode 100644 index 00000000000..0581aa1b7c8 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled_no_annotation.txt @@ -0,0 +1,13 @@ +package + +public fun create(/*0*/ f: (kotlin.Int) -> kotlin.Int): kotlin.Int +public fun create(/*0*/ f: (kotlin.Int) -> kotlin.String): kotlin.String +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 +public fun takeInt(/*0*/ s: kotlin.Int): kotlin.Unit +public fun takeString(/*0*/ s: kotlin.String): kotlin.Unit +public fun test_1(): kotlin.Unit +public fun test_2(): kotlin.Unit +public fun test_3(): kotlin.Unit +public fun test_4(): kotlin.Unit +public fun test_5(): kotlin.Unit diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java index 19287d3aeea..565e76c3781 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java @@ -2824,6 +2824,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW public void testOverloadByLambdaReturnType_enabled() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.kt"); } + + @TestMetadata("overloadByLambdaReturnType_enabled_no_annotation.kt") + public void testOverloadByLambdaReturnType_enabled_no_annotation() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled_no_annotation.kt"); + } } @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/forInArrayLoop") diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java index 3e0458b772c..d4ae24b5c84 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java @@ -2824,6 +2824,11 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno public void testOverloadByLambdaReturnType_enabled() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.kt"); } + + @TestMetadata("overloadByLambdaReturnType_enabled_no_annotation.kt") + public void testOverloadByLambdaReturnType_enabled_no_annotation() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled_no_annotation.kt"); + } } @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/forInArrayLoop")