diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualCallableDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualCallableDeclarationChecker.kt index 88312e77f5e..c9f664ed417 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualCallableDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualCallableDeclarationChecker.kt @@ -10,10 +10,7 @@ import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors -import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration -import org.jetbrains.kotlin.fir.declarations.FirFunction -import org.jetbrains.kotlin.fir.declarations.expectForActual -import org.jetbrains.kotlin.fir.declarations.getSingleExpectForActualOrNull +import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.isActual import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol @@ -32,6 +29,7 @@ object FirActualCallableDeclarationChecker : FirCallableDeclarationChecker() { } private fun checkActualFunctionWithDefaultArguments(function: FirFunction, reporter: DiagnosticReporter, context: CheckerContext) { + if (function.symbol.isAnnotationConstructor(context.session)) return for (valueParameter in function.valueParameters) { if (valueParameter.defaultValue != null) { reporter.reportOn(valueParameter.source, FirErrors.ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS, context) 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 f1f85bd076a..db5b29920c3 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 @@ -122,7 +122,6 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() { ) { val symbol = declaration.symbol val compatibilityToMembersMap = symbol.expectForActual ?: return - val session = context.session checkAmbiguousExpects(symbol, compatibilityToMembersMap, symbol, context, reporter) @@ -131,7 +130,7 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() { if (compatibilityToMembersMap.allStrongIncompatibilities()) return if (Compatible in compatibilityToMembersMap) { - if (checkActual && requireActualModifier(symbol, session)) { + if (checkActual) { reporter.reportOn(source, FirErrors.ACTUAL_MISSING, context) } return @@ -168,13 +167,15 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() { } Compatible !in compatibilityToMembersMap -> { - reporter.reportOn( - source, - FirErrors.ACTUAL_WITHOUT_EXPECT, - symbol, - compatibilityToMembersMap, - context - ) + if (requireActualModifier(declaration.symbol, context.session)) { + reporter.reportOn( + source, + FirErrors.ACTUAL_WITHOUT_EXPECT, + symbol, + compatibilityToMembersMap, + context + ) + } } else -> {} diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirDeclarationBuilder.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirDeclarationBuilder.kt index 160f7f74187..4a18d2756b5 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirDeclarationBuilder.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirDeclarationBuilder.kt @@ -550,7 +550,8 @@ class LightTreeRawFirDeclarationBuilder( selfType.source, classWrapper, delegatedConstructorSource, - containingClassIsExpectClass = status.isExpect + containingClassIsExpectClass = status.isExpect, + isImplicitlyActual = status.isActual && (status.isInline || classKind == ClassKind.ANNOTATION_CLASS) ) val firPrimaryConstructor = primaryConstructorWrapper?.firConstructor firPrimaryConstructor?.let { declarations += it } @@ -884,7 +885,8 @@ class LightTreeRawFirDeclarationBuilder( classWrapper: ClassWrapper, delegatedConstructorSource: KtLightSourceElement?, isEnumEntry: Boolean = false, - containingClassIsExpectClass: Boolean + containingClassIsExpectClass: Boolean, + isImplicitlyActual: Boolean = false, ): PrimaryConstructor? { fun ClassKind.isEnumRelated(): Boolean = this == ClassKind.ENUM_CLASS || this == ClassKind.ENUM_ENTRY val shouldGenerateImplicitConstructor = @@ -955,7 +957,7 @@ class LightTreeRawFirDeclarationBuilder( } val status = FirDeclarationStatusImpl(explicitVisibility ?: defaultVisibility, Modality.FINAL).apply { isExpect = modifiers.hasExpect() || context.containerIsExpect - isActual = modifiers.hasActual() + isActual = modifiers.hasActual() || isImplicitlyActual isInner = classWrapper.isInner() isFromSealedClass = classWrapper.isSealed() && explicitVisibility !== Visibilities.Private isFromEnumClass = classWrapper.isEnum() diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt index 0f0e411cbe0..24604434c4f 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt @@ -983,6 +983,7 @@ open class PsiRawFirBuilder( containingClassIsExpectClass, copyConstructedTypeRefWithImplicitSource = true, isErrorConstructor = !hasPrimaryConstructor, + isImplicitlyActual = container.status.isActual && (container.status.isInline || classKind == ClassKind.ANNOTATION_CLASS) ) container.declarations += firPrimaryConstructor } @@ -1003,6 +1004,7 @@ open class PsiRawFirBuilder( containingClassIsExpectClass: Boolean, copyConstructedTypeRefWithImplicitSource: Boolean, isErrorConstructor: Boolean = false, + isImplicitlyActual: Boolean = false, ): FirConstructor { val constructorSource = this?.toFirSourceElement() ?: owner.toKtPsiSourceElement(KtFakeSourceElementKind.ImplicitConstructor) @@ -1050,7 +1052,7 @@ open class PsiRawFirBuilder( val explicitVisibility = this?.visibility?.takeUnless { it == Visibilities.Unknown } val status = FirDeclarationStatusImpl(explicitVisibility ?: defaultVisibility(), Modality.FINAL).apply { isExpect = this@toFirConstructor?.hasExpectModifier() == true || this@PsiRawFirBuilder.context.containerIsExpect - isActual = this@toFirConstructor?.hasActualModifier() == true + isActual = this@toFirConstructor?.hasActualModifier() == true || isImplicitlyActual isInner = owner.parent.parent !is KtScript && owner.hasModifier(INNER_KEYWORD) // a warning about inner script class is reported on the class itself isFromSealedClass = owner.hasModifier(SEALED_KEYWORD) && explicitVisibility !== Visibilities.Private isFromEnumClass = owner.hasModifier(ENUM_KEYWORD) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatcherTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatcherTransformer.kt index 156cffd5bdf..db523fe330d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatcherTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatcherTransformer.kt @@ -83,7 +83,7 @@ open class FirExpectActualMatcherTransformer( // ------------------------------------------------------ fun transformMemberDeclaration(memberDeclaration: FirMemberDeclaration) { - if (!memberDeclaration.isActual && !memberDeclaration.isImplicitlyActual()) return + if (!memberDeclaration.isActual) return val actualSymbol = memberDeclaration.symbol // Regardless of whether any `expect` symbols are found for `memberDeclaration`, it must be assigned an `expectForActual` map. @@ -97,11 +97,4 @@ open class FirExpectActualMatcherTransformer( ) ?: mapOf() memberDeclaration.expectForActual = expectForActualData } - - // TODO KT-60139 Remove special handling when implicitly actual elements have the actual flag set. - private fun FirMemberDeclaration.isImplicitlyActual(): Boolean { - if (this !is FirPrimaryConstructor) return false - val klass = getContainingClass(session) ?: return false - return klass.isActual && (klass.isInline || klass.classKind == ClassKind.ANNOTATION_CLASS) - } }