diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirExpectActualDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirExpectActualDeclarationChecker.kt index aa7a1872e53..43d36e3b405 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirExpectActualDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirExpectActualDeclarationChecker.kt @@ -138,6 +138,7 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() { actualContainingClass, expectContainingClass, expectActualMatchingContext, + context, ) } else null @@ -220,7 +221,8 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() { expectSymbol: FirBasedSymbol<*>, actualContainingClass: FirRegularClassSymbol?, expectContainingClass: FirRegularClassSymbol?, - context: FirExpectActualMatchingContext, + expectActualMatchingContext: FirExpectActualMatchingContext, + context: CheckerContext, ): ExpectActualCompatibility> = when { actualSymbol is FirCallableSymbol<*> && expectSymbol is FirCallableSymbol<*> -> { @@ -229,14 +231,16 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() { actualSymbol, expectContainingClass, actualContainingClass, - context, + expectActualMatchingContext, + context.languageVersionSettings ) } actualSymbol is FirClassLikeSymbol<*> && expectSymbol is RegularClassSymbolMarker -> { AbstractExpectActualChecker.getClassifiersCompatibility( expectSymbol, actualSymbol, - context, + expectActualMatchingContext, + context.languageVersionSettings ) } else -> error("These expect/actual shouldn't have been matched by FirExpectActualResolver") 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 9a6163a3b56..35e98b405c9 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 @@ -206,7 +207,7 @@ private class ExpectActualLinkCollector : IrElementVisitor, - context: MatchingContext + context: MatchingContext, ) { val matched = AbstractExpectActualMatcher.matchSingleExpectTopLevelDeclarationAgainstPotentialActuals( expectSymbol, @@ -233,6 +234,7 @@ private class ExpectActualLinkCollector : IrElementVisitor, + languageVersionSettings: LanguageVersionSettings, ): ExpectActualCheckingCompatibility { val result = with(context) { getClassifiersCompatibility( expectClassSymbol, actualClassLikeSymbol, parentSubstitutor = null, + languageVersionSettings, ) } @Suppress("UNCHECKED_CAST") @@ -49,6 +52,7 @@ object AbstractExpectActualChecker { expectContainingClass: RegularClassSymbolMarker?, actualContainingClass: RegularClassSymbolMarker?, context: ExpectActualMatchingContext, + languageVersionSettings: LanguageVersionSettings, ): ExpectActualCheckingCompatibility = with (context) { val expectTypeParameters = expectContainingClass?.typeParameters.orEmpty() val actualTypeParameters = actualContainingClass?.typeParameters.orEmpty() @@ -60,6 +64,7 @@ object AbstractExpectActualChecker { parentSubstitutor, expectContainingClass, actualContainingClass, + languageVersionSettings, ) @Suppress("UNCHECKED_CAST") result as ExpectActualCheckingCompatibility @@ -69,6 +74,7 @@ object AbstractExpectActualChecker { expectDeclaration: DeclarationSymbolMarker, actualDeclaration: DeclarationSymbolMarker, context: ExpectActualMatchingContext, + languageVersionSettings: LanguageVersionSettings, ) { with(context) { checkSingleExpectAgainstMatchedActual( @@ -78,6 +84,7 @@ object AbstractExpectActualChecker { expectClassSymbol = null, actualClassSymbol = null, incompatibleMembers = null, + languageVersionSettings, ) } } @@ -88,6 +95,7 @@ object AbstractExpectActualChecker { expectClassSymbol: RegularClassSymbolMarker, actualClassLikeSymbol: ClassLikeSymbolMarker, parentSubstitutor: TypeSubstitutorMarker?, + languageVersionSettings: LanguageVersionSettings, ): ExpectActualCheckingCompatibility<*> { // Can't check FQ names here because nested expected class may be implemented via actual typealias's expansion with the other FQ name require(expectClassSymbol.name == actualClassLikeSymbol.name) { @@ -142,7 +150,7 @@ object AbstractExpectActualChecker { return ExpectActualCheckingCompatibility.Supertypes } - getClassScopesIncompatibility(expectClassSymbol, actualClass, substitutor)?.let { return it } + getClassScopesIncompatibility(expectClassSymbol, actualClass, substitutor, languageVersionSettings)?.let { return it } return ExpectActualCheckingCompatibility.Compatible } @@ -198,6 +206,7 @@ object AbstractExpectActualChecker { expectClassSymbol: RegularClassSymbolMarker, actualClassSymbol: RegularClassSymbolMarker, substitutor: TypeSubstitutorMarker, + languageVersionSettings: LanguageVersionSettings, ): ExpectActualCheckingCompatibility.Incompatible<*>? { val mismatchedMembers = arrayListOf>>>() @@ -228,6 +237,7 @@ object AbstractExpectActualChecker { expectClassSymbol, actualClassSymbol, incompatibleMembers, + languageVersionSettings, ) } } @@ -255,6 +265,7 @@ object AbstractExpectActualChecker { expectClassSymbol: RegularClassSymbolMarker?, actualClassSymbol: RegularClassSymbolMarker?, incompatibleMembers: MutableList, List>>>?, + languageVersionSettings: LanguageVersionSettings, ) { val compatibility = when (expectMember) { is CallableSymbolMarker -> getCallablesCompatibility( @@ -262,7 +273,8 @@ object AbstractExpectActualChecker { actualMember as CallableSymbolMarker, substitutor, expectClassSymbol, - actualClassSymbol + actualClassSymbol, + languageVersionSettings, ) is RegularClassSymbolMarker -> { @@ -271,6 +283,7 @@ object AbstractExpectActualChecker { expectMember, actualMember as ClassLikeSymbolMarker, parentSubstitutor, + languageVersionSettings, ) } else -> error("Unsupported declaration: $expectMember ($actualMember)") @@ -293,6 +306,7 @@ object AbstractExpectActualChecker { parentSubstitutor: TypeSubstitutorMarker?, expectContainingClass: RegularClassSymbolMarker?, actualContainingClass: RegularClassSymbolMarker?, + languageVersionSettings: LanguageVersionSettings, ): ExpectActualCheckingCompatibility<*> { checkCallablesInvariants(expectDeclaration, actualDeclaration) @@ -343,7 +357,13 @@ object AbstractExpectActualChecker { return ExpectActualCheckingCompatibility.Modality } - if (!areCompatibleCallableVisibilities(expectDeclaration.visibility, expectModality, actualDeclaration.visibility)) { + if (!areCompatibleCallableVisibilities( + expectDeclaration.visibility, + expectModality, + actualDeclaration.visibility, + languageVersionSettings + ) + ) { return ExpectActualCheckingCompatibility.Visibility } @@ -384,7 +404,7 @@ object AbstractExpectActualChecker { getFunctionsIncompatibility(expectDeclaration, actualDeclaration)?.let { return it } expectDeclaration is PropertySymbolMarker && actualDeclaration is PropertySymbolMarker -> - getPropertiesIncompatibility(expectDeclaration, actualDeclaration)?.let { return it } + getPropertiesIncompatibility(expectDeclaration, actualDeclaration, languageVersionSettings)?.let { return it } expectDeclaration is EnumEntrySymbolMarker && actualDeclaration is EnumEntrySymbolMarker -> { // do nothing, entries are matched only by name @@ -446,6 +466,7 @@ object AbstractExpectActualChecker { expectVisibility: Visibility, expectModality: Modality?, actualVisibility: Visibility, + languageVersionSettings: LanguageVersionSettings, ): Boolean { val compare = Visibilities.compare(expectVisibility, actualVisibility) return if (expectModality != Modality.FINAL) { @@ -515,12 +536,13 @@ object AbstractExpectActualChecker { private fun getPropertiesIncompatibility( expected: PropertySymbolMarker, actual: PropertySymbolMarker, + languageVersionSettings: LanguageVersionSettings, ): ExpectActualCheckingCompatibility.Incompatible<*>? { return when { !equalBy(expected, actual) { p -> p.isVar } -> ExpectActualCheckingCompatibility.PropertyKind !equalBy(expected, actual) { p -> p.isLateinit } -> ExpectActualCheckingCompatibility.PropertyLateinitModifier expected.isConst && !actual.isConst -> ExpectActualCheckingCompatibility.PropertyConstModifier - !arePropertySettersWithCompatibleVisibilities(expected, actual) -> + !arePropertySettersWithCompatibleVisibilities(expected, actual, languageVersionSettings) -> ExpectActualCheckingCompatibility.PropertySetterVisibility else -> null } @@ -530,6 +552,7 @@ object AbstractExpectActualChecker { private fun arePropertySettersWithCompatibleVisibilities( expected: PropertySymbolMarker, actual: PropertySymbolMarker, + languageVersionSettings: LanguageVersionSettings, ): Boolean { val expectedSetter = expected.setter ?: return true val actualSetter = actual.setter ?: return true @@ -537,6 +560,7 @@ object AbstractExpectActualChecker { expectedSetter.visibility, expectedSetter.modality, actualSetter.visibility, + languageVersionSettings ) }