[IR] 2/2 Propogate expect-actual checker incompatibilities to IR backend
Review: https://jetbrains.team/p/kt/reviews/12750/timeline
This commit is contained in:
+1
-1
@@ -467,7 +467,7 @@ class FirExpectActualMatchingContextImpl private constructor(
|
||||
)
|
||||
}
|
||||
|
||||
override fun onMismatchedOrIncompatibleMembersFromClassScope(
|
||||
override fun onMismatchedMembersFromClassScope(
|
||||
expectSymbol: DeclarationSymbolMarker,
|
||||
actualSymbolsByIncompatibility: Map<ExpectActualMatchingCompatibility.Mismatch, List<DeclarationSymbolMarker>>,
|
||||
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
||||
|
||||
+31
-5
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.backend.common.actualizer
|
||||
|
||||
import org.jetbrains.kotlin.KtDiagnosticReporterWithImplicitIrBasedContext
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.PsiIrFileEntry
|
||||
@@ -22,7 +23,9 @@ import org.jetbrains.kotlin.mpp.DeclarationSymbolMarker
|
||||
import org.jetbrains.kotlin.mpp.RegularClassSymbolMarker
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualChecker
|
||||
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualMatcher
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCheckingCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
||||
import java.io.File
|
||||
|
||||
@@ -201,7 +204,7 @@ private class ExpectActualLinkCollector : IrElementVisitor<Unit, ExpectActualLin
|
||||
}
|
||||
|
||||
private fun matchExpectCallable(declaration: IrDeclarationWithName, callableId: CallableId, context: MatchingContext) {
|
||||
matchExpectDeclaration(
|
||||
matchAndCheckExpectDeclaration(
|
||||
declaration.symbol,
|
||||
context.classActualizationInfo.actualTopLevels[callableId].orEmpty(),
|
||||
context
|
||||
@@ -213,19 +216,27 @@ private class ExpectActualLinkCollector : IrElementVisitor<Unit, ExpectActualLin
|
||||
val classId = declaration.classIdOrFail
|
||||
val expectClassSymbol = declaration.symbol
|
||||
val actualClassLikeSymbol = data.classActualizationInfo.getActualWithoutExpansion(classId)
|
||||
matchExpectDeclaration(expectClassSymbol, listOfNotNull(actualClassLikeSymbol), data)
|
||||
matchAndCheckExpectDeclaration(expectClassSymbol, listOfNotNull(actualClassLikeSymbol), data)
|
||||
}
|
||||
|
||||
private fun matchExpectDeclaration(
|
||||
private fun matchAndCheckExpectDeclaration(
|
||||
expectSymbol: IrSymbol,
|
||||
actualSymbols: List<IrSymbol>,
|
||||
context: MatchingContext
|
||||
) {
|
||||
AbstractExpectActualMatcher.matchSingleExpectTopLevelDeclarationAgainstPotentialActuals(
|
||||
val matched = AbstractExpectActualMatcher.matchSingleExpectTopLevelDeclarationAgainstPotentialActuals(
|
||||
expectSymbol,
|
||||
actualSymbols,
|
||||
context,
|
||||
)
|
||||
if (matched != null) {
|
||||
AbstractExpectActualChecker.checkSingleExpectTopLevelDeclarationAgainstPotentialActuals(
|
||||
expectSymbol,
|
||||
listOf(matched),
|
||||
context,
|
||||
checkClassScopesCompatibility = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitElement(element: IrElement, data: MatchingContext) {
|
||||
@@ -259,7 +270,22 @@ private class ExpectActualLinkCollector : IrElementVisitor<Unit, ExpectActualLin
|
||||
recordActualForExpectDeclaration(expectSymbol, actualSymbol, destination)
|
||||
}
|
||||
|
||||
override fun onMismatchedOrIncompatibleMembersFromClassScope(
|
||||
override fun onIncompatibleMembersFromClassScope(
|
||||
expectSymbol: DeclarationSymbolMarker,
|
||||
actualSymbolsByIncompatibility: Map<ExpectActualCheckingCompatibility.Incompatible<*>, List<DeclarationSymbolMarker>>,
|
||||
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
||||
containingActualClassSymbol: RegularClassSymbolMarker?
|
||||
) {
|
||||
require(expectSymbol is IrSymbol)
|
||||
for ((incompatibility, actualMemberSymbols) in actualSymbolsByIncompatibility) {
|
||||
for (actualSymbol in actualMemberSymbols) {
|
||||
require(actualSymbol is IrSymbol)
|
||||
diagnosticsReporter.reportIncompatibleExpectActual(expectSymbol, actualSymbol, incompatibility)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMismatchedMembersFromClassScope(
|
||||
expectSymbol: DeclarationSymbolMarker,
|
||||
actualSymbolsByIncompatibility: Map<ExpectActualMatchingCompatibility.Mismatch, List<DeclarationSymbolMarker>>,
|
||||
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
||||
|
||||
+1
-2
@@ -318,8 +318,7 @@ object AbstractExpectActualChecker {
|
||||
}
|
||||
|
||||
incompatibleMembers?.add(expectMember to incompatibilityMap)
|
||||
// Temporarily comment out reporting checking incompatibilities to backend. KT-62590 is in progress
|
||||
//onMismatchedOrIncompatibleMembersFromClassScope(expectMember, incompatibilityMap, expectClassSymbol, actualClassSymbol)
|
||||
onIncompatibleMembersFromClassScope(expectMember, incompatibilityMap, expectClassSymbol, actualClassSymbol)
|
||||
}
|
||||
|
||||
context(ExpectActualMatchingContext<*>)
|
||||
|
||||
+15
-15
@@ -9,6 +9,8 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.mpp.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCheckingCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
||||
@@ -50,17 +52,15 @@ object AbstractExpectActualMatcher {
|
||||
expectDeclaration: DeclarationSymbolMarker,
|
||||
actualDeclarations: List<DeclarationSymbolMarker>,
|
||||
context: ExpectActualMatchingContext<T>,
|
||||
) {
|
||||
with(context) {
|
||||
matchSingleExpectAgainstPotentialActuals(
|
||||
expectDeclaration,
|
||||
actualDeclarations,
|
||||
substitutor = null,
|
||||
expectClassSymbol = null,
|
||||
actualClassSymbol = null,
|
||||
unfulfilled = null,
|
||||
)
|
||||
}
|
||||
): DeclarationSymbolMarker? = with(context) {
|
||||
matchSingleExpectAgainstPotentialActuals(
|
||||
expectDeclaration,
|
||||
actualDeclarations,
|
||||
substitutor = null,
|
||||
expectClassSymbol = null,
|
||||
actualClassSymbol = null,
|
||||
mismatchedMembers = null,
|
||||
)
|
||||
}
|
||||
|
||||
fun matchClassifiers(
|
||||
@@ -100,7 +100,7 @@ object AbstractExpectActualMatcher {
|
||||
substitutor,
|
||||
expectClassSymbol,
|
||||
actualClassSymbol,
|
||||
unfulfilled = null,
|
||||
mismatchedMembers = null,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ object AbstractExpectActualMatcher {
|
||||
substitutor: TypeSubstitutorMarker?,
|
||||
expectClassSymbol: RegularClassSymbolMarker?,
|
||||
actualClassSymbol: RegularClassSymbolMarker?,
|
||||
unfulfilled: MutableList<Pair<DeclarationSymbolMarker, Map<ExpectActualMatchingCompatibility.Mismatch, List<DeclarationSymbolMarker?>>>>?,
|
||||
mismatchedMembers: MutableList<Pair<DeclarationSymbolMarker, Map<ExpectActualMatchingCompatibility.Mismatch, List<DeclarationSymbolMarker?>>>>?,
|
||||
): DeclarationSymbolMarker? {
|
||||
val mapping = actualMembers.keysToMap { actualMember ->
|
||||
when (expectMember) {
|
||||
@@ -152,8 +152,8 @@ object AbstractExpectActualMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
unfulfilled?.add(expectMember to incompatibilityMap)
|
||||
onMismatchedOrIncompatibleMembersFromClassScope(expectMember, incompatibilityMap, expectClassSymbol, actualClassSymbol)
|
||||
mismatchedMembers?.add(expectMember to incompatibilityMap)
|
||||
onMismatchedMembersFromClassScope(expectMember, incompatibilityMap, expectClassSymbol, actualClassSymbol)
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
+9
-1
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.mpp.*
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCheckingCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
@@ -172,7 +173,14 @@ interface ExpectActualMatchingContext<T : DeclarationSymbolMarker> : TypeSystemC
|
||||
containingActualClassSymbol: RegularClassSymbolMarker?,
|
||||
) {}
|
||||
|
||||
fun onMismatchedOrIncompatibleMembersFromClassScope(
|
||||
fun onIncompatibleMembersFromClassScope(
|
||||
expectSymbol: DeclarationSymbolMarker,
|
||||
actualSymbolsByIncompatibility: Map<ExpectActualCheckingCompatibility.Incompatible<*>, List<DeclarationSymbolMarker>>,
|
||||
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
||||
containingActualClassSymbol: RegularClassSymbolMarker?,
|
||||
) {}
|
||||
|
||||
fun onMismatchedMembersFromClassScope(
|
||||
expectSymbol: DeclarationSymbolMarker,
|
||||
actualSymbolsByIncompatibility: Map<ExpectActualMatchingCompatibility.Mismatch, List<DeclarationSymbolMarker>>,
|
||||
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
// FILE: common.kt
|
||||
|
||||
interface A
|
||||
<!INCOMPATIBLE_MATCHING{JVM}, INCOMPATIBLE_MATCHING{JVM}!>expect fun <T : A> foo(t: T): String<!>
|
||||
<!INCOMPATIBLE_MATCHING{JVM}!>expect fun <T : A> foo(t: T): String<!>
|
||||
|
||||
// MODULE: m2-jvm()()(m1-common)
|
||||
// FILE: jvm.kt
|
||||
|
||||
+3
-2
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.resolve.multiplatform
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility.Mismatch
|
||||
|
||||
private const val TYPE_PARAMETER_COUNT = "number of type parameters is different"
|
||||
private const val TYPE_PARAMETER_UPPER_BOUNDS = "upper bounds of type parameters are different"
|
||||
|
||||
// Note that the reason is used in the diagnostic output, see PlatformIncompatibilityDiagnosticRenderer
|
||||
/**
|
||||
@@ -37,7 +38,7 @@ sealed class ExpectActualMatchingCompatibility : ExpectActualCompatibility<Nothi
|
||||
object ParameterCount : Mismatch("number of value parameters is different")
|
||||
object FunctionTypeParameterCount : Mismatch(TYPE_PARAMETER_COUNT)
|
||||
object ParameterTypes : Mismatch("parameter types are different")
|
||||
object FunctionTypeParameterUpperBounds : Mismatch("upper bounds of type parameters are different")
|
||||
object FunctionTypeParameterUpperBounds : Mismatch(TYPE_PARAMETER_UPPER_BOUNDS)
|
||||
object MatchedSuccessfully : ExpectActualMatchingCompatibility()
|
||||
}
|
||||
|
||||
@@ -90,7 +91,7 @@ sealed class ExpectActualCheckingCompatibility<out D> : ExpectActualCompatibilit
|
||||
object Modality : Incompatible<Nothing>("modality is different")
|
||||
object Visibility : Incompatible<Nothing>("visibility is different")
|
||||
|
||||
object ClassTypeParameterUpperBounds : Incompatible<Nothing>(ExpectActualMatchingCompatibility.FunctionTypeParameterUpperBounds.reason)
|
||||
object ClassTypeParameterUpperBounds : Incompatible<Nothing>(TYPE_PARAMETER_UPPER_BOUNDS)
|
||||
object TypeParameterVariance : Incompatible<Nothing>("declaration-site variances of type parameters are different")
|
||||
object TypeParameterReified : Incompatible<Nothing>("some type parameter is reified in one declaration and non-reified in the other")
|
||||
object Compatible : ExpectActualCheckingCompatibility<Nothing>()
|
||||
|
||||
Reference in New Issue
Block a user