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 3e71ea75fee..7c55f2442d7 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 @@ -1805,6 +1805,16 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/independentResolutionInLambda.kt"); } + @TestMetadata("multipleOverloads_1.kt") + public void testMultipleOverloads_1() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_1.kt"); + } + + @TestMetadata("multipleOverloads_2.kt") + public void testMultipleOverloads_2() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_2.kt"); + } + @TestMetadata("overloadByLambdaReturnType_disabled.kt") public void testOverloadByLambdaReturnType_disabled() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt"); 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 c8728a4c4a7..9119f7c9ff0 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinCallResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinCallResolver.kt @@ -144,11 +144,17 @@ class KotlinCallResolver( candidates.all { resolutionCallbacks.inferenceSession.shouldRunCompletion(it) } ) { val candidatesWithAnnotation = - candidates.filter { it.resolvedCall.candidateDescriptor.annotations.hasAnnotation(OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION) } + candidates.filterTo(mutableSetOf()) { it.resolvedCall.candidateDescriptor.annotations.hasAnnotation(OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION) } if (candidatesWithAnnotation.isNotEmpty()) { - maximallySpecificCandidates = kotlinCallCompleter.chooseCandidateRegardingFactoryPatternResolution(maximallySpecificCandidates, resolutionCallbacks) + val newCandidates = kotlinCallCompleter.chooseCandidateRegardingFactoryPatternResolution(maximallySpecificCandidates, resolutionCallbacks) + maximallySpecificCandidates = overloadingConflictResolver.chooseMaximallySpecificCandidates( + newCandidates, + CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, + discriminateGenerics = true + ) + if (maximallySpecificCandidates.size > 1) { - maximallySpecificCandidates = candidatesWithAnnotation.toSet() // or revert to original list? + maximallySpecificCandidates = candidatesWithAnnotation } } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt index b5553bd5c25..44870a21fb5 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt @@ -118,9 +118,11 @@ class KotlinCallCompleter( diagnosticHolderForLambda, shouldRunInIndependentContext = true ) - lambdas.getValue(firstCandidate).setAnalyzedResults(results.returnArgumentsInfo, listOf(firstAtom)) val lambdaReturnType = results.lambdaReturnType ?: return candidates + lambdas.getValue(firstCandidate).setAnalyzedResults(results.returnArgumentsInfo, listOf(firstAtom)) + firstCandidate.csBuilder.addSubtypeConstraint(lambdaReturnType, firstAtom.returnType, LambdaArgumentConstraintPosition(firstAtom)) + while (iterator.hasNext()) { val (candidate, atom) = iterator.next() atom.setAnalyzedResults(results.returnArgumentsInfo, firstAtom.subResolvedAtoms!!) diff --git a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_1.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_1.fir.kt new file mode 100644 index 00000000000..fe05dcde048 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_1.fir.kt @@ -0,0 +1,35 @@ +// !LANGUAGE: +NewInference +FactoryPatternResolution +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION -EXPERIMENTAL_API_USAGE -EXPERIMENTAL_UNSIGNED_LITERALS +// ISSUE: KT-11265 + +// FILE: FactoryPattern.kt + +package annotations + +annotation class FactoryPattern + +// FILE: main.kt + +import annotations.FactoryPattern + +@FactoryPattern +fun UByteArray.fooMap(t: (UByte) -> Iterable): List { + TODO("ub.fm") +} + +@FactoryPattern +fun Iterable.fooMap(t: (T) -> Iterable): List { + TODO("i.fm(i)") +} + +@JvmName("fooMapSeq") +fun Iterable.fooMap(t: (T) -> Sequence): List { + TODO("i.fm(s)") +} + +fun test() { + val list = ubyteArrayOf(0u).fooMap { listOf(it) } + takeUByteList(list) +} + +fun takeUByteList(list: List) {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_1.kt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_1.kt new file mode 100644 index 00000000000..ab532327056 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_1.kt @@ -0,0 +1,35 @@ +// !LANGUAGE: +NewInference +FactoryPatternResolution +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION -EXPERIMENTAL_API_USAGE -EXPERIMENTAL_UNSIGNED_LITERALS +// ISSUE: KT-11265 + +// FILE: FactoryPattern.kt + +package annotations + +annotation class FactoryPattern + +// FILE: main.kt + +import annotations.FactoryPattern + +@FactoryPattern +fun UByteArray.fooMap(t: (UByte) -> Iterable): List { + TODO("ub.fm") +} + +@FactoryPattern +fun Iterable.fooMap(t: (T) -> Iterable): List { + TODO("i.fm(i)") +} + +@JvmName("fooMapSeq") +fun Iterable.fooMap(t: (T) -> Sequence): List { + TODO("i.fm(s)") +} + +fun test() { + val list = ubyteArrayOf(0u).fooMap { listOf(it) } + takeUByteList(list) +} + +fun takeUByteList(list: List) {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_1.txt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_1.txt new file mode 100644 index 00000000000..9ab0ab630ce --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_1.txt @@ -0,0 +1,17 @@ +package + +public fun takeUByteList(/*0*/ list: kotlin.collections.List): kotlin.Unit +public fun test(): kotlin.Unit +@annotations.FactoryPattern public fun kotlin.UByteArray.fooMap(/*0*/ t: (kotlin.UByte) -> kotlin.collections.Iterable): kotlin.collections.List +@annotations.FactoryPattern public fun kotlin.collections.Iterable.fooMap(/*0*/ t: (T) -> kotlin.collections.Iterable): kotlin.collections.List +@kotlin.jvm.JvmName(name = "fooMapSeq") public fun kotlin.collections.Iterable.fooMap(/*0*/ t: (T) -> kotlin.sequences.Sequence): kotlin.collections.List + +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/multipleOverloads_2.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_2.fir.kt new file mode 100644 index 00000000000..9ae888bad92 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_2.fir.kt @@ -0,0 +1,29 @@ +// !LANGUAGE: +NewInference +FactoryPatternResolution +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION -EXPERIMENTAL_API_USAGE -EXPERIMENTAL_UNSIGNED_LITERALS +// ISSUE: KT-11265 + +// FILE: FactoryPattern.kt + +package annotations + +annotation class FactoryPattern + +// FILE: main.kt + +import annotations.FactoryPattern + +@FactoryPattern +fun > Iterable.myMaxOf(selector: (T) -> R): R = TODO() +@FactoryPattern +fun Iterable.myMaxOf(selector: (T) -> Double): Double = TODO() +@FactoryPattern +fun Iterable.myMaxOf(selector: (T) -> Float): Float = TODO() + +fun Double.pow(v: Int): Double = this + +fun test() { + val value = listOf(1, 2, 3, 4, 5, 6).myMaxOf { -2.0.pow(it) } + takeDouble(value) +} + +fun takeDouble(value: Double) {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_2.kt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_2.kt new file mode 100644 index 00000000000..560c4f1e521 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_2.kt @@ -0,0 +1,29 @@ +// !LANGUAGE: +NewInference +FactoryPatternResolution +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION -EXPERIMENTAL_API_USAGE -EXPERIMENTAL_UNSIGNED_LITERALS +// ISSUE: KT-11265 + +// FILE: FactoryPattern.kt + +package annotations + +annotation class FactoryPattern + +// FILE: main.kt + +import annotations.FactoryPattern + +@FactoryPattern +fun > Iterable.myMaxOf(selector: (T) -> R): R = TODO() +@FactoryPattern +fun Iterable.myMaxOf(selector: (T) -> Double): Double = TODO() +@FactoryPattern +fun Iterable.myMaxOf(selector: (T) -> Float): Float = TODO() + +fun Double.pow(v: Int): Double = this + +fun test() { + val value = listOf(1, 2, 3, 4, 5, 6).myMaxOf { -2.0.pow(it) } + takeDouble(value) +} + +fun takeDouble(value: Double) {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_2.txt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_2.txt new file mode 100644 index 00000000000..6c067fb3333 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_2.txt @@ -0,0 +1,18 @@ +package + +public fun takeDouble(/*0*/ value: kotlin.Double): kotlin.Unit +public fun test(): kotlin.Unit +@annotations.FactoryPattern public fun > kotlin.collections.Iterable.myMaxOf(/*0*/ selector: (T) -> R): R +@annotations.FactoryPattern public fun kotlin.collections.Iterable.myMaxOf(/*0*/ selector: (T) -> kotlin.Double): kotlin.Double +@annotations.FactoryPattern public fun kotlin.collections.Iterable.myMaxOf(/*0*/ selector: (T) -> kotlin.Float): kotlin.Float +public fun kotlin.Double.pow(/*0*/ v: kotlin.Int): kotlin.Double + +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.kt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.kt index 327593eeefb..f6258409ab2 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 } } @FactoryPattern diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java index 4a4caa521c7..afdb479d6ec 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java @@ -2820,6 +2820,16 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/independentResolutionInLambda.kt"); } + @TestMetadata("multipleOverloads_1.kt") + public void testMultipleOverloads_1() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_1.kt"); + } + + @TestMetadata("multipleOverloads_2.kt") + public void testMultipleOverloads_2() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_2.kt"); + } + @TestMetadata("overloadByLambdaReturnType_disabled.kt") public void testOverloadByLambdaReturnType_disabled() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java index 67b6c376ce5..cf122df09bf 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java @@ -2820,6 +2820,16 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/independentResolutionInLambda.kt"); } + @TestMetadata("multipleOverloads_1.kt") + public void testMultipleOverloads_1() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_1.kt"); + } + + @TestMetadata("multipleOverloads_2.kt") + public void testMultipleOverloads_2() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_2.kt"); + } + @TestMetadata("overloadByLambdaReturnType_disabled.kt") public void testOverloadByLambdaReturnType_disabled() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt");