[FIR] Fix resolving of overload function with expect and common candidates

^KT-58896 Fixed
This commit is contained in:
Ivan Kochurkin
2023-08-29 18:35:55 +02:00
committed by Space Team
parent dc2deea04c
commit c8c25d8b98
19 changed files with 145 additions and 4 deletions
@@ -34159,6 +34159,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectActualTypealiasCoercion.kt");
}
@Test
@TestMetadata("expectAndCommonFunctionOverloads.kt")
public void testExpectAndCommonFunctionOverloads() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectAndCommonFunctionOverloads.kt");
}
@Test
@TestMetadata("expectInterfaceInSupertypes.kt")
public void testExpectInterfaceInSupertypes() throws Exception {
@@ -34159,6 +34159,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectActualTypealiasCoercion.kt");
}
@Test
@TestMetadata("expectAndCommonFunctionOverloads.kt")
public void testExpectAndCommonFunctionOverloads() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectAndCommonFunctionOverloads.kt");
}
@Test
@TestMetadata("expectInterfaceInSupertypes.kt")
public void testExpectInterfaceInSupertypes() throws Exception {
@@ -61,9 +61,6 @@ abstract class AbstractConeCallConflictResolver(
if (isGeneric1 && isGeneric2) return false
}
if (!call1.isExpect && call2.isExpect) return true
if (call1.isExpect && !call2.isExpect) return false
if (call1.contextReceiverCount > call2.contextReceiverCount) return true
if (call1.contextReceiverCount < call2.contextReceiverCount) return false
@@ -8,6 +8,9 @@ package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.getSingleExpectForActualOrNull
import org.jetbrains.kotlin.fir.declarations.utils.isActual
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
import org.jetbrains.kotlin.fir.resolve.inference.ConeTypeParameterBasedTypeVariable
@@ -31,6 +34,7 @@ import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.TypeParameterMarker
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext
import org.jetbrains.kotlin.utils.addToStdlib.runIf
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
typealias CandidateSignature = FlatSignature<Candidate>
@@ -266,7 +270,9 @@ class ConeOverloadConflictResolver(
): Candidate? {
if (candidates.size <= 1) return candidates.singleOrNull()
val candidateSignatures = candidates.map { candidateCall ->
val candidatesWithoutActualizedExpects = filterOutActualizedExpectCandidates(candidates)
val candidateSignatures = candidatesWithoutActualizedExpects.map { candidateCall ->
createFlatSignature(candidateCall)
}
@@ -279,6 +285,23 @@ class ConeOverloadConflictResolver(
return bestCandidatesByParameterTypes.exactMaxWith()?.origin
}
private fun filterOutActualizedExpectCandidates(candidates: Set<Candidate>): Set<Candidate> {
val expectForActualSymbols = candidates
.mapNotNullTo(mutableSetOf()) {
val callableSymbol = it.symbol as? FirCallableSymbol<*> ?: return@mapNotNullTo null
runIf(callableSymbol.isActual) { callableSymbol.getSingleExpectForActualOrNull() }
}
return if (expectForActualSymbols.isEmpty()) {
candidates // Optimization: in most cases, there are no expectForActualSymbols that's why filtering and allocation are not performed
} else {
candidates.filterTo(mutableSetOf()) { candidate ->
val symbol = candidate.symbol
symbol is FirCallableSymbol<*> && (!symbol.isExpect || symbol !in expectForActualSymbols)
}
}
}
/**
* `call1` is not less specific than `call2`
*/
@@ -0,0 +1,26 @@
// IGNORE_BACKEND_K1: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
// !LANGUAGE: +MultiPlatformProjects
// ISSUE: KT-58896
// MODULE: common
// TARGET_PLATFORM: Common
// FILE: common.kt
expect fun f(param: Int): String
fun f(param: Any) = "$param: Any"
fun commonFun() = "${f(1)}; ${f("s")}"
// MODULE: platform()()(common)
// FILE: platform.kt
actual fun f(param: Int) = "$param: Int"
fun platformFun() = "${f(1)}; ${f("s")}"
fun box(): String {
if (commonFun() != "1: Int; s: Any") return "FAIL 1"
if (platformFun() != "1: Int; s: Any") return "FAIL 2"
return "OK"
}
@@ -32491,6 +32491,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectActualTypealias.kt");
}
@Test
@TestMetadata("expectAndCommonFunctionOverloads.kt")
public void testExpectAndCommonFunctionOverloads() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectAndCommonFunctionOverloads.kt");
}
@Test
@TestMetadata("expectInterfaceInSupertypes.kt")
public void testExpectInterfaceInSupertypes() throws Exception {
@@ -34159,6 +34159,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectActualTypealiasCoercion.kt");
}
@Test
@TestMetadata("expectAndCommonFunctionOverloads.kt")
public void testExpectAndCommonFunctionOverloads() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectAndCommonFunctionOverloads.kt");
}
@Test
@TestMetadata("expectInterfaceInSupertypes.kt")
public void testExpectInterfaceInSupertypes() throws Exception {
@@ -34159,6 +34159,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectActualTypealiasCoercion.kt");
}
@Test
@TestMetadata("expectAndCommonFunctionOverloads.kt")
public void testExpectAndCommonFunctionOverloads() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectAndCommonFunctionOverloads.kt");
}
@Test
@TestMetadata("expectInterfaceInSupertypes.kt")
public void testExpectInterfaceInSupertypes() throws Exception {
@@ -29136,6 +29136,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectActualTypealiasCoercion.kt");
}
@TestMetadata("expectAndCommonFunctionOverloads.kt")
public void testExpectAndCommonFunctionOverloads() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectAndCommonFunctionOverloads.kt");
}
@TestMetadata("expectInterfaceInSupertypes.kt")
public void testExpectInterfaceInSupertypes() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectInterfaceInSupertypes.kt");
@@ -23935,6 +23935,12 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectActualTypealias.kt");
}
@Test
@TestMetadata("expectAndCommonFunctionOverloads.kt")
public void testExpectAndCommonFunctionOverloads() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectAndCommonFunctionOverloads.kt");
}
@Test
@TestMetadata("expectInterfaceInSupertypes.kt")
public void testExpectInterfaceInSupertypes() throws Exception {
@@ -23935,6 +23935,12 @@ public class FirJsES6CodegenBoxTestGenerated extends AbstractFirJsES6CodegenBoxT
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectActualTypealias.kt");
}
@Test
@TestMetadata("expectAndCommonFunctionOverloads.kt")
public void testExpectAndCommonFunctionOverloads() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectAndCommonFunctionOverloads.kt");
}
@Test
@TestMetadata("expectInterfaceInSupertypes.kt")
public void testExpectInterfaceInSupertypes() throws Exception {
@@ -23935,6 +23935,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectActualTypealias.kt");
}
@Test
@TestMetadata("expectAndCommonFunctionOverloads.kt")
public void testExpectAndCommonFunctionOverloads() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectAndCommonFunctionOverloads.kt");
}
@Test
@TestMetadata("expectInterfaceInSupertypes.kt")
public void testExpectInterfaceInSupertypes() throws Exception {
@@ -23935,6 +23935,12 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectActualTypealias.kt");
}
@Test
@TestMetadata("expectAndCommonFunctionOverloads.kt")
public void testExpectAndCommonFunctionOverloads() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectAndCommonFunctionOverloads.kt");
}
@Test
@TestMetadata("expectInterfaceInSupertypes.kt")
public void testExpectInterfaceInSupertypes() throws Exception {
@@ -26916,6 +26916,12 @@ public class FirNativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTe
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectActualTypealiasCoercion.kt");
}
@Test
@TestMetadata("expectAndCommonFunctionOverloads.kt")
public void testExpectAndCommonFunctionOverloads() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectAndCommonFunctionOverloads.kt");
}
@Test
@TestMetadata("expectInterfaceInSupertypes.kt")
public void testExpectInterfaceInSupertypes() throws Exception {
@@ -27536,6 +27536,12 @@ public class FirNativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenB
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectActualTypealiasCoercion.kt");
}
@Test
@TestMetadata("expectAndCommonFunctionOverloads.kt")
public void testExpectAndCommonFunctionOverloads() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectAndCommonFunctionOverloads.kt");
}
@Test
@TestMetadata("expectInterfaceInSupertypes.kt")
public void testExpectInterfaceInSupertypes() throws Exception {
@@ -26607,6 +26607,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectActualTypealiasCoercion.kt");
}
@Test
@TestMetadata("expectAndCommonFunctionOverloads.kt")
public void testExpectAndCommonFunctionOverloads() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectAndCommonFunctionOverloads.kt");
}
@Test
@TestMetadata("expectInterfaceInSupertypes.kt")
public void testExpectInterfaceInSupertypes() throws Exception {
@@ -26917,6 +26917,12 @@ public class NativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenBoxT
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectActualTypealiasCoercion.kt");
}
@Test
@TestMetadata("expectAndCommonFunctionOverloads.kt")
public void testExpectAndCommonFunctionOverloads() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectAndCommonFunctionOverloads.kt");
}
@Test
@TestMetadata("expectInterfaceInSupertypes.kt")
public void testExpectInterfaceInSupertypes() throws Exception {
@@ -23689,6 +23689,12 @@ public class FirWasmCodegenBoxTestGenerated extends AbstractFirWasmCodegenBoxTes
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectActualTypealias.kt");
}
@Test
@TestMetadata("expectAndCommonFunctionOverloads.kt")
public void testExpectAndCommonFunctionOverloads() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectAndCommonFunctionOverloads.kt");
}
@Test
@TestMetadata("expectInterfaceInSupertypes.kt")
public void testExpectInterfaceInSupertypes() throws Exception {
@@ -23689,6 +23689,12 @@ public class K1WasmCodegenBoxTestGenerated extends AbstractK1WasmCodegenBoxTest
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectActualTypealias.kt");
}
@Test
@TestMetadata("expectAndCommonFunctionOverloads.kt")
public void testExpectAndCommonFunctionOverloads() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/expectAndCommonFunctionOverloads.kt");
}
@Test
@TestMetadata("expectInterfaceInSupertypes.kt")
public void testExpectInterfaceInSupertypes() throws Exception {