From 8722e142f65ffe9966262ed89af924404885c9db Mon Sep 17 00:00:00 2001 From: Nikita Bobko Date: Tue, 17 Oct 2023 12:47:10 +0200 Subject: [PATCH] [IR] 2/2 Propogate expect-actual checker incompatibilities to IR backend Review: https://jetbrains.team/p/kt/reviews/12750/timeline --- .../mpp/FirExpectActualMatchingContextImpl.kt | 2 +- .../actualizer/ExpectActualCollector.kt | 36 ++++++++++++++++--- .../calls/mpp/AbstractExpectActualChecker.kt | 3 +- .../calls/mpp/AbstractExpectActualMatcher.kt | 30 ++++++++-------- .../calls/mpp/ExpectActualMatchingContext.kt | 10 +++++- ...VsGenericsUpperBoundIncompatibility.fir.kt | 2 +- .../ExpectActualCompatibility.kt | 5 +-- 7 files changed, 61 insertions(+), 27 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatchingContextImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatchingContextImpl.kt index be6a28f454e..77d9722f046 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatchingContextImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatchingContextImpl.kt @@ -467,7 +467,7 @@ class FirExpectActualMatchingContextImpl private constructor( ) } - override fun onMismatchedOrIncompatibleMembersFromClassScope( + override fun onMismatchedMembersFromClassScope( expectSymbol: DeclarationSymbolMarker, actualSymbolsByIncompatibility: Map>, containingExpectClassSymbol: RegularClassSymbolMarker?, diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/ExpectActualCollector.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/ExpectActualCollector.kt index a34b8d65764..8706bbb7724 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/ExpectActualCollector.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/ExpectActualCollector.kt @@ -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, 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, List>, + 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>, containingExpectClassSymbol: RegularClassSymbolMarker?, diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/AbstractExpectActualChecker.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/AbstractExpectActualChecker.kt index 6452ede366f..445aae5ae9b 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/AbstractExpectActualChecker.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/AbstractExpectActualChecker.kt @@ -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<*>) diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/AbstractExpectActualMatcher.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/AbstractExpectActualMatcher.kt index ffe27f1414b..25d39d4e751 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/AbstractExpectActualMatcher.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/AbstractExpectActualMatcher.kt @@ -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, context: ExpectActualMatchingContext, - ) { - 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>>>?, + mismatchedMembers: MutableList>>>?, ): 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 } diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/ExpectActualMatchingContext.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/ExpectActualMatchingContext.kt index 3107e3a5c5e..4253a522510 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/ExpectActualMatchingContext.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/ExpectActualMatchingContext.kt @@ -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 : TypeSystemC containingActualClassSymbol: RegularClassSymbolMarker?, ) {} - fun onMismatchedOrIncompatibleMembersFromClassScope( + fun onIncompatibleMembersFromClassScope( + expectSymbol: DeclarationSymbolMarker, + actualSymbolsByIncompatibility: Map, List>, + containingExpectClassSymbol: RegularClassSymbolMarker?, + containingActualClassSymbol: RegularClassSymbolMarker?, + ) {} + + fun onMismatchedMembersFromClassScope( expectSymbol: DeclarationSymbolMarker, actualSymbolsByIncompatibility: Map>, containingExpectClassSymbol: RegularClassSymbolMarker?, diff --git a/compiler/testData/diagnostics/tests/multiplatform/returnTypeVsGenericsUpperBoundIncompatibility.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/returnTypeVsGenericsUpperBoundIncompatibility.fir.kt index 824097c280c..862ee341e36 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/returnTypeVsGenericsUpperBoundIncompatibility.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/returnTypeVsGenericsUpperBoundIncompatibility.fir.kt @@ -2,7 +2,7 @@ // FILE: common.kt interface A -expect fun foo(t: T): String +expect fun foo(t: T): String // MODULE: m2-jvm()()(m1-common) // FILE: jvm.kt diff --git a/core/compiler.common/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectActualCompatibility.kt b/core/compiler.common/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectActualCompatibility.kt index b5a79890ba9..7f1185ea5e1 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectActualCompatibility.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectActualCompatibility.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 : ExpectActualCompatibilit object Modality : Incompatible("modality is different") object Visibility : Incompatible("visibility is different") - object ClassTypeParameterUpperBounds : Incompatible(ExpectActualMatchingCompatibility.FunctionTypeParameterUpperBounds.reason) + object ClassTypeParameterUpperBounds : Incompatible(TYPE_PARAMETER_UPPER_BOUNDS) object TypeParameterVariance : Incompatible("declaration-site variances of type parameters are different") object TypeParameterReified : Incompatible("some type parameter is reified in one declaration and non-reified in the other") object Compatible : ExpectActualCheckingCompatibility()