diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java index f5ed15ce852..52b68678bad 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java @@ -32476,6 +32476,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityDisabled.kt"); } + @Test + @TestMetadata("samPriorityVsGenericCompatibilityEnabled.kt") + public void testSamPriorityVsGenericCompatibilityEnabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityEnabled.kt"); + } + @Test @TestMetadata("sameCandidatesFromKotlinAndJavaInOneScope.kt") public void testSameCandidatesFromKotlinAndJavaInOneScope() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java index 5b49e315a0e..594b55f84a8 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java @@ -32476,6 +32476,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityDisabled.kt"); } + @Test + @TestMetadata("samPriorityVsGenericCompatibilityEnabled.kt") + public void testSamPriorityVsGenericCompatibilityEnabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityEnabled.kt"); + } + @Test @TestMetadata("sameCandidatesFromKotlinAndJavaInOneScope.kt") public void testSameCandidatesFromKotlinAndJavaInOneScope() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java index ef58bc7a351..bb54b201722 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java @@ -30310,6 +30310,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityDisabled.kt"); } + @Test + @TestMetadata("samPriorityVsGenericCompatibilityEnabled.kt") + public void testSamPriorityVsGenericCompatibilityEnabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityEnabled.kt"); + } + @Test @TestMetadata("sameCandidatesFromKotlinAndJavaInOneScope.kt") public void testSameCandidatesFromKotlinAndJavaInOneScope() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java index 7a504e49a7f..d7ae2eb1d2e 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java @@ -30322,6 +30322,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityDisabled.kt"); } + @Test + @TestMetadata("samPriorityVsGenericCompatibilityEnabled.kt") + public void testSamPriorityVsGenericCompatibilityEnabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityEnabled.kt"); + } + @Test @TestMetadata("sameCandidatesFromKotlinAndJavaInOneScope.kt") public void testSameCandidatesFromKotlinAndJavaInOneScope() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt index 23bd9e5f647..5a519530a51 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt @@ -35,7 +35,7 @@ import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment abstract class AbstractConeCallConflictResolver( private val specificityComparator: TypeSpecificityComparator, protected val inferenceComponents: InferenceComponents, - private val transformerComponents: BodyResolveComponents, + protected val transformerComponents: BodyResolveComponents, private val considerMissingArgumentsInSignatures: Boolean, ) : ConeCallConflictResolver() { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeOverloadConflictResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeOverloadConflictResolver.kt index 7f11a7752dc..878bff8b6a3 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeOverloadConflictResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeOverloadConflictResolver.kt @@ -163,6 +163,11 @@ class ConeOverloadConflictResolver( discriminateSuspendConversions: Boolean, discriminateByUnwrappedSmartCastOrigin: Boolean, ): Set { + val withoutLowPrioritySAM = candidates.filterTo(mutableSetOf()) { !it.shouldHaveLowPriorityDueToSAM(transformerComponents) } + if (withoutLowPrioritySAM.size == 1) { + return withoutLowPrioritySAM + } + findMaximallySpecificCall(candidates, false)?.let { return setOf(it) } if (discriminateGenerics) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt index 135d99bf6ba..14034b35076 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.matchingParameterFunctionType import org.jetbrains.kotlin.fir.references.FirSuperReference import org.jetbrains.kotlin.fir.references.FirThisReference +import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents import org.jetbrains.kotlin.fir.resolve.directExpansionType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.inference.* @@ -512,7 +513,7 @@ internal object CheckArguments : CheckerStage() { } // Logic description: only candidates from Kotlin, but using Java SAM types, are discriminated - candidate.usesSAM && !candidate.isJavaApplicableCandidate() -> { + candidate.shouldHaveLowPriorityDueToSAM(context.bodyResolveComponents) -> { if (argumentMapping.values.any { val coneType = it.returnTypeRef.coneType context.bodyResolveComponents.samResolver.isSamType(coneType) && @@ -527,6 +528,16 @@ internal object CheckArguments : CheckerStage() { } } +internal fun Candidate.shouldHaveLowPriorityDueToSAM(bodyResolveComponents: BodyResolveComponents): Boolean { + if (!usesSAM || isJavaApplicableCandidate()) return false + return argumentMapping!!.values.any { + val coneType = it.returnTypeRef.coneType + bodyResolveComponents.samResolver.isSamType(coneType) && + // Candidate is not from Java, so no flexible types are possible here + coneType.toRegularClassSymbol(bodyResolveComponents.session)?.isJavaOrEnhancement == true + } +} + private fun Candidate.isJavaApplicableCandidate(): Boolean { val symbol = symbol as? FirFunctionSymbol ?: return false if (symbol.isJavaOrEnhancement) return true diff --git a/compiler/testData/diagnostics/tests/j+k/sam/compatibilityResolveToOuterScopeForKotlinFunctions.fir.kt b/compiler/testData/diagnostics/tests/j+k/sam/compatibilityResolveToOuterScopeForKotlinFunctions.fir.kt index 11415254d19..eb1fa1074ed 100644 --- a/compiler/testData/diagnostics/tests/j+k/sam/compatibilityResolveToOuterScopeForKotlinFunctions.fir.kt +++ b/compiler/testData/diagnostics/tests/j+k/sam/compatibilityResolveToOuterScopeForKotlinFunctions.fir.kt @@ -41,7 +41,7 @@ object Test3 { fun test(f: () -> Unit) { val result = foo(1, f) - result + result } } @@ -53,7 +53,7 @@ object Test4 { fun test() { val result = foo(1, ::bar) - result + result } } diff --git a/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGeneric.kt b/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGeneric.kt index 5acf822f49d..5bd51db6cc4 100644 --- a/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGeneric.kt +++ b/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGeneric.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // SKIP_TXT // FULL_JDK @@ -7,6 +8,6 @@ fun bar(action: java.lang.Runnable) { } fun foo(): String = "" fun main() { - val x = bar() { foo() } // OK with default current 1.5/1.6, Error with DisableCompatibilityModeForNewInference enabled + val x = bar() { foo() } // OK with default current 1.5/1.6, Error with DisableCompatibilityModeForNewInference enabled, Ok in K2 x.length } diff --git a/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGeneric.fir.kt b/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityDisabled.fir.kt similarity index 60% rename from compiler/testData/diagnostics/tests/samConversions/samPriorityVsGeneric.fir.kt rename to compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityDisabled.fir.kt index 67300b10c94..33223b6b586 100644 --- a/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGeneric.fir.kt +++ b/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityDisabled.fir.kt @@ -1,3 +1,4 @@ +// !LANGUAGE: +DisableCompatibilityModeForNewInference // SKIP_TXT // FULL_JDK @@ -7,6 +8,6 @@ fun bar(action: java.lang.Runnable) { } fun foo(): String = "" fun main() { - val x = bar() { foo() } // OK with default current 1.5/1.6, Error with DisableCompatibilityModeForNewInference enabled - x.length + val x = bar() { foo() } // OK with default current 1.5/1.6, Error with DisableCompatibilityModeForNewInference enabled, Ok in K2 + x.length } diff --git a/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityDisabled.kt b/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityDisabled.kt index 80b75729482..a5792e2e1e3 100644 --- a/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityDisabled.kt +++ b/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityDisabled.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +DisableCompatibilityModeForNewInference // SKIP_TXT -// FIR_IDENTICAL // FULL_JDK fun bar(action: () -> T): T = action() @@ -9,6 +8,6 @@ fun bar(action: java.lang.Runnable) { } fun foo(): String = "" fun main() { - val x = bar() { foo() } // OK with default current 1.5/1.6, Error with DisableCompatibilityModeForNewInference enabled + val x = bar() { foo() } // OK with default current 1.5/1.6, Error with DisableCompatibilityModeForNewInference enabled, Ok in K2 x.length } diff --git a/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityEnabled.kt b/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityEnabled.kt new file mode 100644 index 00000000000..38261e337d8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityEnabled.kt @@ -0,0 +1,14 @@ +// FIR_IDENTICAL +// !LANGUAGE: -DisableCompatibilityModeForNewInference +// SKIP_TXT +// FULL_JDK + +fun bar(action: () -> T): T = action() +fun bar(action: java.lang.Runnable) { } + +fun foo(): String = "" + +fun main() { + val x = bar() { foo() } // OK with default current 1.5/1.6, Error with DisableCompatibilityModeForNewInference enabled, Ok in K2 + x.length +} 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 fd66c4ab443..f37f43eb908 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 @@ -32476,6 +32476,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityDisabled.kt"); } + @Test + @TestMetadata("samPriorityVsGenericCompatibilityEnabled.kt") + public void testSamPriorityVsGenericCompatibilityEnabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityEnabled.kt"); + } + @Test @TestMetadata("sameCandidatesFromKotlinAndJavaInOneScope.kt") public void testSameCandidatesFromKotlinAndJavaInOneScope() throws Exception {