diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt index f6d9ab2985d..1808d04707e 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt @@ -49,7 +49,6 @@ object CommonDeclarationCheckers : DeclarationCheckers() { FirKClassWithIncorrectTypeArgumentChecker, FirImplicitNothingReturnTypeChecker, FirDynamicReceiverChecker, - FirActualCallableDeclarationChecker, ) override val functionCheckers: Set 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 deleted file mode 100644 index 41e785374df..00000000000 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualCallableDeclarationChecker.kt +++ /dev/null @@ -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>>, - context - ) - } - } -} diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ExpectActualUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ExpectActualUtils.kt index 39c724cc2e3..65c9ef02481 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ExpectActualUtils.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ExpectActualUtils.kt @@ -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>, @@ -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 - ) -} \ No newline at end of file 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 155505a99b9..95e1b46909a 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 @@ -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?, diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrExpectActualMatchingContext.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrExpectActualMatchingContext.kt index b24661c1766..4ab8abd4be5 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrExpectActualMatchingContext.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrExpectActualMatchingContext.kt @@ -92,9 +92,6 @@ internal abstract class IrExpectActualMatchingContext( private inline fun DeclarationSymbolMarker.safeAsIr(): T? = (this as IrSymbol).owner as? T - override val shouldCheckReturnTypesOfCallables: Boolean - get() = true - override val innerClassesCapturesOuterTypeParameters: Boolean get() = false 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 a4dfe0d2b6c..ad27d550287 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 @@ -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 }) { 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 7e542266071..edcdb13f179 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 @@ -20,8 +20,6 @@ import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker import org.jetbrains.kotlin.types.model.TypeSystemContext interface ExpectActualMatchingContext : TypeSystemContext { - val shouldCheckReturnTypesOfCallables: Boolean - /* * This flag indicates how are type parameters of inner classes stored in the specific implementation of RegularClassSymbolMarker * diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/nestedAnnotationClassViaActualTypealias.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/nestedAnnotationClassViaActualTypealias.fir.kt index 7643467e5de..8534be0c5bf 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/nestedAnnotationClassViaActualTypealias.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/nestedAnnotationClassViaActualTypealias.fir.kt @@ -11,4 +11,4 @@ class DefaultArgsInNestedClassImpl { } // Incompatible because of bug KT-31636 -actual typealias DefaultArgsInNestedClass = DefaultArgsInNestedClassImpl +actual typealias DefaultArgsInNestedClass = DefaultArgsInNestedClassImpl diff --git a/compiler/testData/diagnostics/tests/multiplatform/hmpp/kt57320.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/hmpp/kt57320.fir.kt index d6589436b7c..9964773b496 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/hmpp/kt57320.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/hmpp/kt57320.fir.kt @@ -34,7 +34,7 @@ interface KotlinXStringDemoInterface { // FILE: StringDemoInterface.kt actual typealias StringDemoInterface = KotlinXStringDemoInterface -actual fun StringDemoInterface.; The following declaration is incompatible: expect fun StringDemoInterface.plusK(): String")!>plusK() = StringValue(value).plus("K").value +actual fun StringDemoInterface.; The following declaration is incompatible because return type is different: expect fun StringDemoInterface.plusK(): String")!>plusK() = StringValue(value).plus("K").value // FILE: main.kt class StringDemo(override val value: String) : StringDemoInterface diff --git a/compiler/testData/multiplatform/classScopes/functionIncorrectSignature/output.txt b/compiler/testData/multiplatform/classScopes/functionIncorrectSignature/output.txt index 7bd91571d6b..cb1857c85ce 100644 --- a/compiler/testData/multiplatform/classScopes/functionIncorrectSignature/output.txt +++ b/compiler/testData/multiplatform/classScopes/functionIncorrectSignature/output.txt @@ -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() diff --git a/compiler/testData/multiplatform/classScopes/functionIncorrectSignatureFromSuperclass/output.txt b/compiler/testData/multiplatform/classScopes/functionIncorrectSignatureFromSuperclass/output.txt index e0977091f21..393a89914f3 100644 --- a/compiler/testData/multiplatform/classScopes/functionIncorrectSignatureFromSuperclass/output.txt +++ b/compiler/testData/multiplatform/classScopes/functionIncorrectSignatureFromSuperclass/output.txt @@ -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() + ^ diff --git a/compiler/testData/multiplatform/incompatibleCallables/output.txt b/compiler/testData/multiplatform/incompatibleCallables/output.txt index c251dda5e82..a35212f5557 100644 --- a/compiler/testData/multiplatform/incompatibleCallables/output.txt +++ b/compiler/testData/multiplatform/incompatibleCallables/output.txt @@ -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 = ""