[FIR, IR] Run DefaultArgumentsInExpectActualizedByFakeOverride not only in FIR but in IR as well

Review: https://jetbrains.team/p/kt/reviews/13334/timeline

Thanks to the previous commit, it's now possible to run
DefaultArgumentsInExpectActualizedByFakeOverride on both: frontend (FIR)
and backend (IR).

We aim to perform a thorough examination of checks involving
fake-overrides on both FIR and IR, given their distinct implementations
for handling fake-overrides.

The commit decreases scope of influence of hacky
`shouldCheckDefaultParams` flag.
This commit is contained in:
Nikita Bobko
2023-12-01 17:13:37 +01:00
committed by Space Team
parent 1aeefe6c33
commit 2a7403a979
12 changed files with 113 additions and 36 deletions
@@ -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
}
}