[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:
Nikita Bobko
2023-10-17 12:47:10 +02:00
committed by teamcity
parent eb0c8c00c3
commit 8722e142f6
7 changed files with 61 additions and 27 deletions
@@ -467,7 +467,7 @@ class FirExpectActualMatchingContextImpl private constructor(
)
}
override fun onMismatchedOrIncompatibleMembersFromClassScope(
override fun onMismatchedMembersFromClassScope(
expectSymbol: DeclarationSymbolMarker,
actualSymbolsByIncompatibility: Map<ExpectActualMatchingCompatibility.Mismatch, List<DeclarationSymbolMarker>>,
containingExpectClassSymbol: RegularClassSymbolMarker?,
@@ -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?,
@@ -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<*>)
@@ -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
}
@@ -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?,
@@ -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
@@ -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>()