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 e7825116a5c..1d41a3d9c5e 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 @@ -25249,6 +25249,18 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/samConversions/samConversionsWithSmartCasts.kt"); } + @Test + @TestMetadata("samPriorityVsGeneric.kt") + public void testSamPriorityVsGeneric() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/samPriorityVsGeneric.kt"); + } + + @Test + @TestMetadata("samPriorityVsGenericCompatibilityDisabled.kt") + public void testSamPriorityVsGenericCompatibilityDisabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityDisabled.kt"); + } + @Test @TestMetadata("sameCandidatesFromKotlinAndJavaInOneScope.kt") public void testSameCandidatesFromKotlinAndJavaInOneScope() 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 01de14e6298..90cd7cab772 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 @@ -25249,6 +25249,18 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/samConversions/samConversionsWithSmartCasts.kt"); } + @Test + @TestMetadata("samPriorityVsGeneric.kt") + public void testSamPriorityVsGeneric() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/samPriorityVsGeneric.kt"); + } + + @Test + @TestMetadata("samPriorityVsGenericCompatibilityDisabled.kt") + public void testSamPriorityVsGenericCompatibilityDisabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityDisabled.kt"); + } + @Test @TestMetadata("sameCandidatesFromKotlinAndJavaInOneScope.kt") public void testSameCandidatesFromKotlinAndJavaInOneScope() 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 626e9bb9ce0..6285dbe0d3e 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 @@ -25249,6 +25249,18 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/samConversions/samConversionsWithSmartCasts.kt"); } + @Test + @TestMetadata("samPriorityVsGeneric.kt") + public void testSamPriorityVsGeneric() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/samPriorityVsGeneric.kt"); + } + + @Test + @TestMetadata("samPriorityVsGenericCompatibilityDisabled.kt") + public void testSamPriorityVsGenericCompatibilityDisabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityDisabled.kt"); + } + @Test @TestMetadata("sameCandidatesFromKotlinAndJavaInOneScope.kt") public void testSameCandidatesFromKotlinAndJavaInOneScope() throws Exception { 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 724b13ea659..5688e2ab601 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 @@ -5,26 +5,27 @@ package org.jetbrains.kotlin.fir.resolve.calls +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.fir.FirVisibilityChecker +import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.expressions.* -import org.jetbrains.kotlin.fir.matchingParameterFunctionType import org.jetbrains.kotlin.fir.references.FirSuperReference import org.jetbrains.kotlin.fir.resolve.directExpansionType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.inference.* import org.jetbrains.kotlin.fir.resolve.isTypeMismatchDueToNullability import org.jetbrains.kotlin.fir.resolve.toSymbol +import org.jetbrains.kotlin.fir.scopes.FirTypeScope import org.jetbrains.kotlin.fir.scopes.FirUnstableSmartcastTypeScope +import org.jetbrains.kotlin.fir.scopes.ProcessorAction +import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.SyntheticSymbol import org.jetbrains.kotlin.fir.symbols.ensureResolved import org.jetbrains.kotlin.fir.symbols.impl.* -import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.fir.visibilityChecker import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -351,12 +352,42 @@ internal object CheckArguments : CheckerStage() { context = context ) } - if (candidate.system.hasContradiction && callInfo.arguments.isNotEmpty()) { - sink.yieldDiagnostic(InapplicableCandidate) + + when { + candidate.system.hasContradiction && callInfo.arguments.isNotEmpty() -> { + sink.yieldDiagnostic(InapplicableCandidate) + } + candidate.usesSAM && !candidate.isJavaApplicableCandidate() -> { + sink.markCandidateForCompatibilityResolve(context) + } } } } +private fun Candidate.isJavaApplicableCandidate(): Boolean { + val symbol = symbol as? FirNamedFunctionSymbol ?: return false + if (symbol.origin == FirDeclarationOrigin.Enhancement) return true + if (originScope !is FirTypeScope) return false + + var result = false + + originScope.processOverriddenFunctions(symbol) { + if (it.origin == FirDeclarationOrigin.Enhancement) { + result = true + ProcessorAction.STOP + } else { + ProcessorAction.NEXT + } + } + + return result +} + +private fun CheckerSink.markCandidateForCompatibilityResolve(context: ResolutionContext) { + if (context.session.languageVersionSettings.supportsFeature(LanguageFeature.DisableCompatibilityModeForNewInference)) return + reportDiagnostic(LowerPriorityToPreserveCompatibilityDiagnostic) +} + internal object EagerResolveOfCallableReferences : CheckerStage() { override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) { if (candidate.postponedAtoms.isEmpty()) return @@ -368,7 +399,7 @@ internal object EagerResolveOfCallableReferences : CheckerStage() { sink.yieldDiagnostic(InapplicableCandidate) } else when (applicability) { CandidateApplicability.RESOLVED_NEED_PRESERVE_COMPATIBILITY -> - candidate.addDiagnostic(LowerPriorityToPreserveCompatibilityDiagnostic) + sink.reportDiagnostic(LowerPriorityToPreserveCompatibilityDiagnostic) else -> { } } diff --git a/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGeneric.kt b/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGeneric.kt new file mode 100644 index 00000000000..6954b8cf17d --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGeneric.kt @@ -0,0 +1,13 @@ +// SKIP_TXT +// FIR_IDENTICAL +// 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 + x.length +} diff --git a/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityDisabled.kt b/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityDisabled.kt new file mode 100644 index 00000000000..80b75729482 --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityDisabled.kt @@ -0,0 +1,14 @@ +// !LANGUAGE: +DisableCompatibilityModeForNewInference +// SKIP_TXT +// FIR_IDENTICAL +// 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 + 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 dd32b556d7b..de42d30096c 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 @@ -25261,6 +25261,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/samConversions/samConversionsWithSmartCasts.kt"); } + @Test + @TestMetadata("samPriorityVsGeneric.kt") + public void testSamPriorityVsGeneric() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/samPriorityVsGeneric.kt"); + } + + @Test + @TestMetadata("samPriorityVsGenericCompatibilityDisabled.kt") + public void testSamPriorityVsGenericCompatibilityDisabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/samPriorityVsGenericCompatibilityDisabled.kt"); + } + @Test @TestMetadata("sameCandidatesFromKotlinAndJavaInOneScope.kt") public void testSameCandidatesFromKotlinAndJavaInOneScope() throws Exception {