diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt index a271f3516ff..f77ff7c43bf 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -2868,6 +2868,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE) { firDiagnostic -> + DefaultValueNotAllowedInOverrideImpl( + firDiagnostic as KtPsiDiagnostic, + token, + ) + } add(FirErrors.FUN_INTERFACE_CONSTRUCTOR_REFERENCE) { firDiagnostic -> FunInterfaceConstructorReferenceImpl( firDiagnostic as KtPsiDiagnostic, diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt index 88d4e67f1d5..a831038ceb5 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt @@ -2032,6 +2032,10 @@ sealed interface KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = DataObjectCustomEqualsOrHashCode::class } + interface DefaultValueNotAllowedInOverride : KtFirDiagnostic { + override val diagnosticClass get() = DefaultValueNotAllowedInOverride::class + } + interface FunInterfaceConstructorReference : KtFirDiagnostic { override val diagnosticClass get() = FunInterfaceConstructorReference::class } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index cb25869ed7b..b4f97b6d928 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -2439,6 +2439,11 @@ internal class DataObjectCustomEqualsOrHashCodeImpl( token: KtLifetimeToken, ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.DataObjectCustomEqualsOrHashCode +internal class DefaultValueNotAllowedInOverrideImpl( + firDiagnostic: KtPsiDiagnostic, + token: KtLifetimeToken, +) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.DefaultValueNotAllowedInOverride + internal class FunInterfaceConstructorReferenceImpl( firDiagnostic: KtPsiDiagnostic, token: KtLifetimeToken, diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index eaa92842422..4c04f466bc3 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -1009,6 +1009,10 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { val DATA_OBJECT_CUSTOM_EQUALS_OR_HASH_CODE by error(PositioningStrategy.OVERRIDE_MODIFIER) } + val PARAMETER_DEFAULT_VALUES by object : DiagnosticGroup("Parameter default values") { + val DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE by error() + } + val FUN_INTERFACES by object : DiagnosticGroup("Fun interfaces") { val FUN_INTERFACE_CONSTRUCTOR_REFERENCE by error(PositioningStrategy.REFERENCE_BY_QUALIFIED) val FUN_INTERFACE_WRONG_COUNT_OF_ABSTRACT_MEMBERS by error(PositioningStrategy.FUN_MODIFIER) diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 45536238ce0..492a80119ea 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -527,6 +527,9 @@ object FirErrors { val TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED by warning0(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED) val DATA_OBJECT_CUSTOM_EQUALS_OR_HASH_CODE by error0(SourceElementPositioningStrategies.OVERRIDE_MODIFIER) + // Parameter default values + val DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE by error0() + // Fun interfaces val FUN_INTERFACE_CONSTRUCTOR_REFERENCE by error0(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) val FUN_INTERFACE_WRONG_COUNT_OF_ABSTRACT_MEMBERS by error0(SourceElementPositioningStrategies.FUN_MODIFIER) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt index 03329eb083e..bb37eb6e869 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt @@ -217,6 +217,19 @@ object FirOverrideChecker : FirClassChecker() { return null } + @OptIn(SymbolInternals::class) + private fun FirFunctionSymbol<*>.checkDefaultValues( + reporter: DiagnosticReporter, + context: CheckerContext, + ) { + for (valueParameterSymbol in valueParameterSymbols) { + val defaultValue = valueParameterSymbol.fir.defaultValue + if (defaultValue != null) { + reporter.reportOn(defaultValue.source, FirErrors.DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE, context) + } + } + } + private fun checkMember( member: FirCallableSymbol<*>, containingClass: FirClass, @@ -299,6 +312,10 @@ object FirOverrideChecker : FirClassChecker() { member.checkDeprecation(reporter, overriddenMemberSymbols, context) + if (member is FirFunctionSymbol) { + member.checkDefaultValues(reporter, context) + } + val restriction = member.checkReturnType( overriddenSymbols = overriddenMemberSymbols, typeCheckerState = typeCheckerState, diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt index de7ba59041a..2467179a2b4 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt @@ -153,6 +153,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_WITHOU import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_OBJECT_CUSTOM_EQUALS_OR_HASH_CODE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DECLARATION_CANT_BE_INLINED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEFAULT_ARGUMENTS_IN_EXPECT_WITH_ACTUAL_TYPEALIAS +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEFINITELY_NON_NULLABLE_AS_REIFIED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATED_PROPERTY_INSIDE_VALUE_CLASS @@ -1643,6 +1644,9 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() { map.put(TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED, "Tail recursion optimization inside try/catch/finally is not supported") map.put(DATA_OBJECT_CUSTOM_EQUALS_OR_HASH_CODE, "Data object cannot have a custom implementation of 'equals' or 'hashCode'") + // Parameter default values + map.put(DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE, "An overriding function is not allowed to specify default values for its parameters.") + // Fun interfaces map.put(FUN_INTERFACE_CONSTRUCTOR_REFERENCE, "Functional/SAM interface constructor references are prohibited") diff --git a/compiler/testData/diagnostics/tests/dataClasses/dataClassExplicitlyOverridingCopyWithDefaults.fir.kt b/compiler/testData/diagnostics/tests/dataClasses/dataClassExplicitlyOverridingCopyWithDefaults.fir.kt index 4e62292ae3a..9a9905684e2 100644 --- a/compiler/testData/diagnostics/tests/dataClasses/dataClassExplicitlyOverridingCopyWithDefaults.fir.kt +++ b/compiler/testData/diagnostics/tests/dataClasses/dataClassExplicitlyOverridingCopyWithDefaults.fir.kt @@ -5,5 +5,5 @@ interface WithCopy { } data class Test(val str: String) : WithCopy { - override fun copy(str: String = this.str) = Test(str) -} \ No newline at end of file + override fun copy(str: String = this.str) = Test(str) +} diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedInheritsDefaultArguments.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedInheritsDefaultArguments.fir.kt deleted file mode 100644 index 2028994eaa1..00000000000 --- a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedInheritsDefaultArguments.fir.kt +++ /dev/null @@ -1,36 +0,0 @@ -// MODULE: m1-common -// FILE: common.kt - -interface Foo { - fun ok(x: Int, y: String = "") - - fun failX(x: Int, y: String = "") - - fun failY(x: Int, y: String = "") -} - -expect class Bar : Foo { - override fun ok(x: Int, y: String) - - override fun failX(x: Int, y: String) - - override fun failY(x: Int, y: String) -} - -fun test(foo: Foo, bar: Bar) { - foo.ok(42) - foo.ok(42, "OK") - bar.ok(42) - bar.ok(42, "OK") -} - -// MODULE: m2-jvm()()(m1-common) -// FILE: jvm.kt - -actual class Bar : Foo { - actual override fun ok(x: Int, y: String) {} - - actual override fun failX(x: Int = 0, y: String) {} - - actual override fun failY(x: Int, y: String = "") {} -} diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedInheritsDefaultArguments.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedInheritsDefaultArguments.kt index 2db6594a13d..238da2d43db 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedInheritsDefaultArguments.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedInheritsDefaultArguments.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // MODULE: m1-common // FILE: common.kt diff --git a/compiler/testData/diagnostics/tests/override/DefaultParameterValueInOverride.fir.kt b/compiler/testData/diagnostics/tests/override/DefaultParameterValueInOverride.fir.kt deleted file mode 100644 index ddae0ca41b4..00000000000 --- a/compiler/testData/diagnostics/tests/override/DefaultParameterValueInOverride.fir.kt +++ /dev/null @@ -1,13 +0,0 @@ -open class A { - open fun foo(a : Int) {} -} - -class C : A() { - override fun foo(a : Int = 1) { - } -} - -class D : A() { - override fun foo(a : Int = 1) { - } -} diff --git a/compiler/testData/diagnostics/tests/override/DefaultParameterValueInOverride.kt b/compiler/testData/diagnostics/tests/override/DefaultParameterValueInOverride.kt index 804e30479a1..54f224a68f8 100644 --- a/compiler/testData/diagnostics/tests/override/DefaultParameterValueInOverride.kt +++ b/compiler/testData/diagnostics/tests/override/DefaultParameterValueInOverride.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL open class A { open fun foo(a : Int) {} }