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