From b15787bfa8db085164599a501cb193ec61958794 Mon Sep 17 00:00:00 2001 From: Nikita Bobko Date: Tue, 19 Sep 2023 12:18:42 +0200 Subject: [PATCH] Fir incorrect usage of `AbstractExpectActualCompatibilityChecker.getCallablesCompatibility` API ^KT-62027 Fixed `getCallablesCompatibility` requires parentSubstitutor as a parameter, but we created a member-level substitutor `getCallablesCompatibility` will create member-level substitutor itself, no need to create member-level substitutor on the call site. IndexOutOfBounds was happening in an attempt of creating member-level substitutor I will refactor the `createExpectActualTypeParameterSubstitutor` API in the following commits later. It will help to avoid problems like that --- ...ndMPPDiagnosticsWithLightTreeTestGenerated.java | 6 ++++++ ...FrontendMPPDiagnosticsWithPsiTestGenerated.java | 6 ++++++ ...SameMembersAsNonFinalExpectClassifierChecker.kt | 10 ++++------ .../kt62027.fir.kt | 14 ++++++++++++++ .../kt62027.kt | 14 ++++++++++++++ .../test/runners/DiagnosticTestGenerated.java | 6 ++++++ 6 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/multiplatform/actualClassifierMustHasTheSameMembersAsNonFinalExpectClassifierChecker/kt62027.fir.kt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/actualClassifierMustHasTheSameMembersAsNonFinalExpectClassifierChecker/kt62027.kt diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated.java index c37a59c965d..14cc733c2d3 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated.java @@ -640,6 +640,12 @@ public class FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated extends Abst runTest("compiler/testData/diagnostics/tests/multiplatform/actualClassifierMustHasTheSameMembersAsNonFinalExpectClassifierChecker/injectVarargParameterOverload.kt"); } + @Test + @TestMetadata("kt62027.kt") + public void testKt62027() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/actualClassifierMustHasTheSameMembersAsNonFinalExpectClassifierChecker/kt62027.kt"); + } + @Test @TestMetadata("memberScopeMismatch_oldLanguageVersion.kt") public void testMemberScopeMismatch_oldLanguageVersion() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithPsiTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithPsiTestGenerated.java index 9f45429befd..3586124f1ef 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithPsiTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithPsiTestGenerated.java @@ -640,6 +640,12 @@ public class FirOldFrontendMPPDiagnosticsWithPsiTestGenerated extends AbstractFi runTest("compiler/testData/diagnostics/tests/multiplatform/actualClassifierMustHasTheSameMembersAsNonFinalExpectClassifierChecker/injectVarargParameterOverload.kt"); } + @Test + @TestMetadata("kt62027.kt") + public void testKt62027() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/actualClassifierMustHasTheSameMembersAsNonFinalExpectClassifierChecker/kt62027.kt"); + } + @Test @TestMetadata("memberScopeMismatch_oldLanguageVersion.kt") public void testMemberScopeMismatch_oldLanguageVersion() throws Exception { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ActualClassifierMustHasTheSameMembersAsNonFinalExpectClassifierChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ActualClassifierMustHasTheSameMembersAsNonFinalExpectClassifierChecker.kt index 62622cac1c8..d4626958126 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ActualClassifierMustHasTheSameMembersAsNonFinalExpectClassifierChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ActualClassifierMustHasTheSameMembersAsNonFinalExpectClassifierChecker.kt @@ -137,6 +137,9 @@ private fun calculateExpectActualScopeDiff( actual: ClassDescriptor, ): Set> { val matchingContext = ClassicExpectActualMatchingContext(actual.module) + // It's responsibility of AbstractExpectActualCompatibilityChecker to report that. Most probably this check is redundant, + // because we can't reach this line if expect and actual don't match, but let's have it for safety + if (expect.declaredTypeParameters.size != actual.declaredTypeParameters.size) return emptySet() val classTypeSubstitutor = matchingContext.createExpectActualTypeParameterSubstitutor( expect.declaredTypeParameters, actual.declaredTypeParameters, @@ -156,15 +159,10 @@ private fun calculateExpectActualScopeDiff( } else { potentialExpects .map { expectMember -> - val substitutor = matchingContext.createExpectActualTypeParameterSubstitutor( - expectMember.typeParameters, - actualMember.typeParameters, - classTypeSubstitutor - ) AbstractExpectActualCompatibilityChecker.getCallablesCompatibility( expectMember, actualMember, - substitutor, + classTypeSubstitutor, expect, actual, matchingContext diff --git a/compiler/testData/diagnostics/tests/multiplatform/actualClassifierMustHasTheSameMembersAsNonFinalExpectClassifierChecker/kt62027.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/actualClassifierMustHasTheSameMembersAsNonFinalExpectClassifierChecker/kt62027.fir.kt new file mode 100644 index 00000000000..e144e7456b4 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/actualClassifierMustHasTheSameMembersAsNonFinalExpectClassifierChecker/kt62027.fir.kt @@ -0,0 +1,14 @@ +// MODULE: m1-common +// FILE: common.kt + +expect open class Foo { + fun foo(t: T) +} + +// MODULE: m2-jvm()()(m1-common) +// FILE: jvm.kt + +actual open class Foo { + actual fun foo(t: T) {} + fun foo(t: String) {} +} diff --git a/compiler/testData/diagnostics/tests/multiplatform/actualClassifierMustHasTheSameMembersAsNonFinalExpectClassifierChecker/kt62027.kt b/compiler/testData/diagnostics/tests/multiplatform/actualClassifierMustHasTheSameMembersAsNonFinalExpectClassifierChecker/kt62027.kt new file mode 100644 index 00000000000..b0279d1d708 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/actualClassifierMustHasTheSameMembersAsNonFinalExpectClassifierChecker/kt62027.kt @@ -0,0 +1,14 @@ +// MODULE: m1-common +// FILE: common.kt + +expect open class Foo { + fun foo(t: T) +} + +// MODULE: m2-jvm()()(m1-common) +// FILE: jvm.kt + +actual open class Foo { + actual fun foo(t: T) {} + fun foo(t: String) {} +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 7e4fa6f4f5a..c8b191eae91 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -23641,6 +23641,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/multiplatform/actualClassifierMustHasTheSameMembersAsNonFinalExpectClassifierChecker/injectVarargParameterOverload.kt"); } + @Test + @TestMetadata("kt62027.kt") + public void testKt62027() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/actualClassifierMustHasTheSameMembersAsNonFinalExpectClassifierChecker/kt62027.kt"); + } + @Test @TestMetadata("memberScopeMismatch_oldLanguageVersion.kt") public void testMemberScopeMismatch_oldLanguageVersion() throws Exception {