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 d5cd1123a25..c15f1ec1258 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 @@ -369,32 +369,31 @@ object AbstractExpectActualChecker { getTypeParametersVarianceOrReifiedIncompatibility(expectedTypeParameters, actualTypeParameters)?.let { return it } + if (languageVersionSettings.supportsFeature(LanguageFeature.ProhibitDefaultArgumentsInExpectActualizedByFakeOverride) && + // If expect declaration is a fake-override then default params came from common + // supertypes of actual class and expect class. It's a valid code. + !expectDeclaration.isFakeOverride(expectContainingClass) && + (actualDeclaration.isFakeOverride(actualContainingClass) || actualDeclaration.isDelegatedMember) && + expectDeclaration.valueParameters.any { it.hasDefaultValueNonRecursive } + ) { + return ExpectActualCheckingCompatibility.DefaultArgumentsInExpectActualizedByFakeOverride + } + if (shouldCheckDefaultParams && // "parameters" checks are required only for functions, because only functions can have parameters - actualDeclaration is FunctionSymbolMarker && expectDeclaration is FunctionSymbolMarker + actualDeclaration is FunctionSymbolMarker && expectDeclaration is FunctionSymbolMarker && + // Actual annotation constructors can have default argument values; their consistency with arguments in the expected annotation + // is checked in ExpectedActualDeclarationChecker.checkAnnotationConstructors + !actualDeclaration.isAnnotationConstructor() ) { - if (languageVersionSettings.supportsFeature(LanguageFeature.ProhibitDefaultArgumentsInExpectActualizedByFakeOverride) && - // If expect declaration is a fake-override then default params came from common - // supertypes of actual class and expect class. It's a valid code. - !expectDeclaration.isFakeOverride(expectContainingClass) && - (actualDeclaration.isFakeOverride(actualContainingClass) || actualDeclaration.isDelegatedMember) && - expectDeclaration.valueParameters.any { it.hasDefaultValueNonRecursive } - ) { - return ExpectActualCheckingCompatibility.DefaultArgumentsInExpectActualizedByFakeOverride - } - val expectOverriddenDeclarations = expectDeclaration.allRecursivelyOverriddenDeclarationsIncludingSelf(expectContainingClass).toSet() val actualOverriddenDeclarations = actualDeclaration.allRecursivelyOverriddenDeclarationsIncludingSelf(actualContainingClass) - // Actual annotation constructors can have default argument values; their consistency with arguments in the expected annotation - // is checked in ExpectedActualDeclarationChecker.checkAnnotationConstructors - if (!actualDeclaration.isAnnotationConstructor() && - // If default params came from common supertypes of actual class and expect class then it's a valid code. - // Here we filter out such default params. - (actualOverriddenDeclarations - expectOverriddenDeclarations).flatMap { it.valueParameters }.any { it.hasDefaultValue } - ) { + // If default params came from common supertypes of actual class and expect class then it's a valid code. + // Here we filter out such default params. + if ((actualOverriddenDeclarations - expectOverriddenDeclarations).flatMap { it.valueParameters }.any { it.hasDefaultValue }) { return ExpectActualCheckingCompatibility.ActualFunctionWithDefaultParameters } } diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/delegation2.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/delegation2.fir.kt index 5073964e819..7230eef3e47 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/delegation2.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/delegation2.fir.kt @@ -1,8 +1,8 @@ // MODULE: m1-common // FILE: common.kt -expect class Foo { - fun foo(p: Int = 1) -} +expect class Foo { + fun foo(p: Int = 1) +} // MODULE: m2-jvm()()(m1-common) // FILE: jvm.kt diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/delegation2.ll.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/delegation2.ll.kt new file mode 100644 index 00000000000..5073964e819 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/delegation2.ll.kt @@ -0,0 +1,17 @@ +// MODULE: m1-common +// FILE: common.kt +expect class Foo { + fun foo(p: Int = 1) +} + +// MODULE: m2-jvm()()(m1-common) +// FILE: jvm.kt +interface Base { + fun foo(p: Int) +} + +object BaseImpl : Base { + override fun foo(p: Int) {} +} + +actual class Foo : Base by BaseImpl diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/intersectionOverride.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/intersectionOverride.fir.kt index a2dc9c4d496..227e8be5b8f 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/intersectionOverride.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/intersectionOverride.fir.kt @@ -1,8 +1,8 @@ // MODULE: m1-common // FILE: common.kt -expect interface Foo { - fun foo(p: Int = 1) -} +expect interface Foo { + fun foo(p: Int = 1) +} // MODULE: m2-jvm()()(m1-common) // FILE: jvm.kt diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/intersectionOverride.ll.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/intersectionOverride.ll.kt new file mode 100644 index 00000000000..a2dc9c4d496 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/intersectionOverride.ll.kt @@ -0,0 +1,18 @@ +// MODULE: m1-common +// FILE: common.kt +expect interface Foo { + fun foo(p: Int = 1) +} + +// MODULE: m2-jvm()()(m1-common) +// FILE: jvm.kt +interface Base1 { + fun foo(p: Int) +} + +interface Base2 { + fun foo(p: Int) +} + +@Suppress("ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_SUPERTYPES_AS_NON_FINAL_EXPECT_CLASSIFIER_WARNING") +actual interface Foo : Base1, Base2 diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/nestedClass.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/nestedClass.fir.kt index 22fc908b885..2854699ba9d 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/nestedClass.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/nestedClass.fir.kt @@ -1,10 +1,10 @@ // MODULE: m1-common // FILE: common.kt -expect class Foo { - class Bar() { - fun foo(p: Int = 1) - } -} +expect class Foo { + class Bar() { + fun foo(p: Int = 1) + } +} // MODULE: m2-jvm()()(m1-common) // FILE: jvm.kt diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/nestedClass.ll.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/nestedClass.ll.kt new file mode 100644 index 00000000000..22fc908b885 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/nestedClass.ll.kt @@ -0,0 +1,17 @@ +// MODULE: m1-common +// FILE: common.kt +expect class Foo { + class Bar() { + fun foo(p: Int = 1) + } +} + +// MODULE: m2-jvm()()(m1-common) +// FILE: jvm.kt +open class Base { + fun foo(p: Int) {} +} + +actual class Foo { + actual class Bar : Base() +} diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/simple.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/simple.fir.kt index 141b2a74d0e..a3a9e4befdd 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/simple.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/simple.fir.kt @@ -1,8 +1,8 @@ // MODULE: m1-common // FILE: common.kt -expect class Foo { - fun foo(param: Int = 1) -} +expect class Foo { + fun foo(param: Int = 1) +} // MODULE: m2-jvm()()(m1-common) // FILE: jvm.kt diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/simple.ll.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/simple.ll.kt new file mode 100644 index 00000000000..141b2a74d0e --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/simple.ll.kt @@ -0,0 +1,13 @@ +// MODULE: m1-common +// FILE: common.kt +expect class Foo { + fun foo(param: Int = 1) +} + +// MODULE: m2-jvm()()(m1-common) +// FILE: jvm.kt +open class Base { + fun foo(param: Int) {} +} + +actual class Foo : Base() diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/simpleIncompatible.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/simpleIncompatible.fir.kt index ee329c2bf1d..3b94c283e85 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/simpleIncompatible.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/simpleIncompatible.fir.kt @@ -1,7 +1,7 @@ // MODULE: m1-common // FILE: common.kt expect class Foo { - fun foo(param: Int = 1) + fun foo(param: Int = 1) fun missingOnActual() } diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/substitutionOverride.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/substitutionOverride.fir.kt index 765a13e81f3..cf1e640587f 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/substitutionOverride.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/substitutionOverride.fir.kt @@ -1,8 +1,8 @@ // MODULE: m1-common // FILE: common.kt -expect class Foo() { - fun foo(p: Int = 1) -} +expect class Foo() { + fun foo(p: Int = 1) +} // MODULE: m2-jvm()()(m1-common) // FILE: jvm.kt diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/substitutionOverride.ll.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/substitutionOverride.ll.kt new file mode 100644 index 00000000000..765a13e81f3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/methodDefaultArgsViaActualFakeOverride/substitutionOverride.ll.kt @@ -0,0 +1,13 @@ +// MODULE: m1-common +// FILE: common.kt +expect class Foo() { + fun foo(p: Int = 1) +} + +// MODULE: m2-jvm()()(m1-common) +// FILE: jvm.kt +open class Base { + fun foo(p: T) {} +} + +actual class Foo : Base()