[FIR] 2/2 Cleanup: drop no longer necessary FirActualCallableDeclarationChecker

It became possible to drop it after KT-62590. Now, on a frontend, the
return type check is part of a common AbstractExpectActualChecker logic

Change in nestedAnnotationClassViaActualTypealias.fir.kt aligns the
behaviour with K1. KT-61964

Review: https://jetbrains.team/p/kt/reviews/12750/timeline
This commit is contained in:
Nikita Bobko
2023-10-25 20:56:21 +02:00
committed by teamcity
parent a9583e4f9a
commit 75a0442b61
12 changed files with 26 additions and 130 deletions
@@ -49,7 +49,6 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirKClassWithIncorrectTypeArgumentChecker,
FirImplicitNothingReturnTypeChecker,
FirDynamicReceiverChecker,
FirActualCallableDeclarationChecker,
)
override val functionCheckers: Set<FirFunctionChecker>
@@ -1,69 +0,0 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
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.expectForActual
import org.jetbrains.kotlin.fir.declarations.getSingleExpectForActualOrNull
import org.jetbrains.kotlin.fir.declarations.utils.isActual
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.types.areCompatibleExpectActualTypes
import org.jetbrains.kotlin.fir.types.createExpectActualTypeParameterSubstitutor
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
import org.jetbrains.kotlin.utils.zipIfSizesAreEqual
object FirActualCallableDeclarationChecker : FirCallableDeclarationChecker() {
override fun check(declaration: FirCallableDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (!declaration.isActual) return
checkReturnTypes(declaration, context, reporter)
}
private fun checkReturnTypes(callableDeclaration: FirCallableDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
val actualFunctionSymbol = callableDeclaration.symbol
val expectFunctionSymbol = actualFunctionSymbol.getSingleExpectForActualOrNull() as? FirCallableSymbol ?: return
val expectTypeParameters = expectFunctionSymbol.getContainingClassSymbol(expectFunctionSymbol.moduleData.session)
?.typeParameterSymbols.orEmpty()
val actualClassTypeParameters = actualFunctionSymbol.getContainingClassSymbol(context.session)?.typeParameterSymbols.orEmpty()
val parentSubstitutor = createExpectActualTypeParameterSubstitutor(
// It's responsibility of AbstractExpectActualCompatibilityChecker to report that
(expectTypeParameters zipIfSizesAreEqual actualClassTypeParameters) ?: return,
context.session
)
val substitutor = createExpectActualTypeParameterSubstitutor(
// It's responsibility of AbstractExpectActualCompatibilityChecker to check that
(expectFunctionSymbol.typeParameterSymbols zipIfSizesAreEqual actualFunctionSymbol.typeParameterSymbols) ?: return,
context.session,
parentSubstitutor
)
if (!areCompatibleExpectActualTypes(
substitutor.substituteOrSelf(expectFunctionSymbol.resolvedReturnType.type),
actualFunctionSymbol.resolvedReturnType.type,
context.session,
dynamicTypesEqualToAnything = false
)
) {
reporter.reportOn(
callableDeclaration.source,
FirErrors.ACTUAL_WITHOUT_EXPECT,
actualFunctionSymbol,
actualFunctionSymbol.expectForActual as Map<ExpectActualMatchingCompatibility, Collection<FirBasedSymbol<*>>>,
context
)
}
}
}
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
import org.jetbrains.kotlin.fir.resolve.substitution.chain
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.types.AbstractTypeChecker
fun createExpectActualTypeParameterSubstitutor(
expectActualTypeParameters: List<Pair<FirTypeParameterSymbol, FirTypeParameterSymbol>>,
@@ -29,28 +28,3 @@ fun createExpectActualTypeParameterSubstitutor(
}
return substitutor.chain(parentSubstitutor)
}
// Copy-pasted to org.jetbrains.kotlin.fir.resolve.transformers.mpp.FirExpectActualMatchingContextImpl.areCompatibleExpectActualTypes
fun areCompatibleExpectActualTypes(
expectedType: ConeKotlinType?,
actualType: ConeKotlinType?,
actualSession: FirSession,
dynamicTypesEqualToAnything: Boolean = true
): Boolean {
if (expectedType == null) return actualType == null
if (actualType == null) return false
if (!dynamicTypesEqualToAnything) {
val isExpectedDynamic = expectedType is ConeDynamicType
val isActualDynamic = actualType is ConeDynamicType
if (isExpectedDynamic && !isActualDynamic || !isExpectedDynamic && isActualDynamic) {
return false
}
}
return AbstractTypeChecker.equalTypes(
actualSession.typeContext,
expectedType,
actualType
)
}
@@ -43,9 +43,6 @@ class FirExpectActualMatchingContextImpl private constructor(
private val scopeSession: ScopeSession,
private val allowedWritingMemberExpectForActualMapping: Boolean,
) : FirExpectActualMatchingContext, TypeSystemContext by actualSession.typeContext {
override val shouldCheckReturnTypesOfCallables: Boolean
get() = false
override val shouldCheckAbsenceOfDefaultParamsInActual: Boolean
get() = true
@@ -303,7 +300,6 @@ class FirExpectActualMatchingContextImpl private constructor(
override val TypeParameterSymbolMarker.isReified: Boolean
get() = asSymbol().isReified
// Copy-pasted to org.jetbrains.kotlin.fir.types.ExpectActualUtilsKt.areCompatibleExpectActualTypes
override fun areCompatibleExpectActualTypes(
expectType: KotlinTypeMarker?,
actualType: KotlinTypeMarker?,
@@ -92,9 +92,6 @@ internal abstract class IrExpectActualMatchingContext(
private inline fun <reified T : IrDeclaration> DeclarationSymbolMarker.safeAsIr(): T? = (this as IrSymbol).owner as? T
override val shouldCheckReturnTypesOfCallables: Boolean
get() = true
override val innerClassesCapturesOuterTypeParameters: Boolean
get() = false
@@ -362,22 +362,20 @@ object AbstractExpectActualChecker {
val expectedValueParameters = expectDeclaration.valueParameters
val actualValueParameters = actualDeclaration.valueParameters
if (shouldCheckReturnTypesOfCallables) {
val substitutor = createExpectActualTypeParameterSubstitutor(
(expectedTypeParameters zipIfSizesAreEqual actualTypeParameters)
?: error("expect/actual type parameters sizes are checked earlier"),
parentSubstitutor
)
val substitutor = createExpectActualTypeParameterSubstitutor(
(expectedTypeParameters zipIfSizesAreEqual actualTypeParameters)
?: error("expect/actual type parameters sizes are checked earlier"),
parentSubstitutor
)
if (!areCompatibleExpectActualTypes(
substitutor.safeSubstitute(expectDeclaration.returnType),
actualDeclaration.returnType,
parameterOfAnnotationComparisonMode = insideAnnotationClass,
dynamicTypesEqualToAnything = false
)
) {
return ExpectActualCheckingCompatibility.ReturnType
}
if (!areCompatibleExpectActualTypes(
substitutor.safeSubstitute(expectDeclaration.returnType),
actualDeclaration.returnType,
parameterOfAnnotationComparisonMode = insideAnnotationClass,
dynamicTypesEqualToAnything = false
)
) {
return ExpectActualCheckingCompatibility.ReturnType
}
if (actualDeclaration.hasStableParameterNames && !equalsBy(expectedValueParameters, actualValueParameters) { it.name }) {
@@ -20,8 +20,6 @@ import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
import org.jetbrains.kotlin.types.model.TypeSystemContext
interface ExpectActualMatchingContext<T : DeclarationSymbolMarker> : TypeSystemContext {
val shouldCheckReturnTypesOfCallables: Boolean
/*
* This flag indicates how are type parameters of inner classes stored in the specific implementation of RegularClassSymbolMarker
*
@@ -11,4 +11,4 @@ class DefaultArgsInNestedClassImpl {
}
// Incompatible because of bug KT-31636
actual typealias DefaultArgsInNestedClass = DefaultArgsInNestedClassImpl
actual typealias <!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>DefaultArgsInNestedClass<!> = DefaultArgsInNestedClassImpl
@@ -34,7 +34,7 @@ interface KotlinXStringDemoInterface {
// FILE: StringDemoInterface.kt
actual typealias StringDemoInterface = KotlinXStringDemoInterface
actual fun StringDemoIn<!EXPECT_ACTUAL_INCOMPATIBILITY!>terface.<!ACTUAL_WITHOUT_EXPECT("actual fun StringDemoInterface.plusK(): <ERROR TYPE REF: Unresolved name: value>; The following declaration is incompatible: expect fun StringDemoInterface.plusK(): String")!>plusK<!>() = <!EXPECT_CLASS_AS_FUNCTION!>StringValue<!>(value).plus("K")<!>.<!UNRESOLVED_REFERENCE!>value<!>
actual fun StringDemoIn<!EXPECT_ACTUAL_INCOMPATIBILITY!>terface.<!ACTUAL_WITHOUT_EXPECT("actual fun StringDemoInterface.plusK(): <ERROR TYPE REF: Unresolved name: value>; The following declaration is incompatible because return type is different: expect fun StringDemoInterface.plusK(): String")!>plusK<!>() = <!EXPECT_CLASS_AS_FUNCTION!>StringValue<!>(value).plus("K")<!>.<!UNRESOLVED_REFERENCE!>value<!>
// FILE: main.kt
class StringDemo(override val value: String) : StringDemoInterface
@@ -6,7 +6,7 @@ Output:
Exit code: COMPILATION_ERROR
Output:
compiler/testData/multiplatform/classScopes/functionIncorrectSignature/jvm.kt:2:16: error: 'actual fun function(b: ByteArray): Long' has no corresponding expected declaration
The following declaration is incompatible:
The following declaration is incompatible because return type is different:
expect fun function(b: ByteArray): Int
actual fun function(b: ByteArray): Long = b.size.toLong()
@@ -5,9 +5,12 @@ Output:
-- JVM --
Exit code: COMPILATION_ERROR
Output:
compiler/testData/multiplatform/classScopes/functionIncorrectSignatureFromSuperclass/common.kt:1:1: error: expect declaration `Foo` doesn't match actual `Foo` because some expected members have no actual ones
expect class Foo {
^
compiler/testData/multiplatform/classScopes/functionIncorrectSignatureFromSuperclass/common.kt:2:5: error: expect declaration `function` doesn't match actual `function` because return type is different
fun function(b: ByteArray): Int
^
compiler/testData/multiplatform/classScopes/functionIncorrectSignatureFromSuperclass/jvm.kt:5:14: error: 'actual class Foo : Base' has no corresponding members for expected class members:
expect fun function(b: ByteArray): Int
The following declaration is incompatible because return type is different:
fun function(b: ByteArray): Long
actual class Foo : Base()
^
@@ -6,7 +6,7 @@ Output:
Exit code: COMPILATION_ERROR
Output:
compiler/testData/multiplatform/incompatibleCallables/jvm.kt:1:12: error: 'actual fun f1(): String' has no corresponding expected declaration
The following declaration is incompatible:
The following declaration is incompatible because return type is different:
expect fun f1(): Unit
actual fun f1(): String = ""