diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index ad304ee9991..bc286d844be 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -37850,6 +37850,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/bodyUsagesAndInline.kt"); } + @Test + @TestMetadata("callOfBaseFunctionFromGeneric.kt") + public void testCallOfBaseFunctionFromGeneric() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/callOfBaseFunctionFromGeneric.kt"); + } + @Test @TestMetadata("classMembers.kt") public void testClassMembers() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 7dfc125fb2f..564f2f611d9 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -37850,6 +37850,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/bodyUsagesAndInline.kt"); } + @Test + @TestMetadata("callOfBaseFunctionFromGeneric.kt") + public void testCallOfBaseFunctionFromGeneric() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/callOfBaseFunctionFromGeneric.kt"); + } + @Test @TestMetadata("classMembers.kt") public void testClassMembers() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 2355ee3d2ce..42e2b311dab 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -37850,6 +37850,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/bodyUsagesAndInline.kt"); } + @Test + @TestMetadata("callOfBaseFunctionFromGeneric.kt") + public void testCallOfBaseFunctionFromGeneric() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/callOfBaseFunctionFromGeneric.kt"); + } + @Test @TestMetadata("classMembers.kt") public void testClassMembers() throws Exception { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirOptInUsageBaseChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirOptInUsageBaseChecker.kt index 743cd90468d..9750c2661f9 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirOptInUsageBaseChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirOptInUsageBaseChecker.kt @@ -159,16 +159,20 @@ object FirOptInUsageBaseChecker { if (this is FirNamedFunctionSymbol) { parentClassScope?.processDirectlyOverriddenFunctions(this) { it.loadExperimentalities( - context, result, visited, fromSetter = false, dispatchReceiverType = null, fromSupertype = false + context, result, visited, fromSetter = false, dispatchReceiverType, fromSupertype = false ) ProcessorAction.NEXT } } else if (this is FirPropertySymbol) { parentClassScope?.processDirectlyOverriddenProperties(this) { - it.loadExperimentalities(context, result, visited, fromSetter, dispatchReceiverType = null, fromSupertype = false) + it.loadExperimentalities(context, result, visited, fromSetter, dispatchReceiverType, fromSupertype = false) ProcessorAction.NEXT } } + } else if (dispatchReceiverType == null) { + parentClassSymbol?.loadExperimentalities( + context, result, visited, fromSetter = false, dispatchReceiverType = null, fromSupertype = false + ) } if (fir !is FirConstructor) { // Without coneTypeSafe v fails in MT test (FirRenderer.kt) @@ -180,13 +184,7 @@ object FirOptInUsageBaseChecker { } } } - if (dispatchReceiverType == null) { - parentClassSymbol?.loadExperimentalities( - context, result, visited, fromSetter = false, dispatchReceiverType = null, fromSupertype = false - ) - } else { - dispatchReceiverType.addExperimentalities(context, result, visited) - } + dispatchReceiverType?.addExperimentalities(context, result, visited) if (fromSetter && this is FirPropertySymbol) { setterSymbol?.loadExperimentalities( context, result, visited, fromSetter = false, dispatchReceiverType, fromSupertype = false diff --git a/compiler/testData/diagnostics/testsWithStdLib/experimental/callOfBaseFunctionFromGeneric.kt b/compiler/testData/diagnostics/testsWithStdLib/experimental/callOfBaseFunctionFromGeneric.kt new file mode 100644 index 00000000000..5f5e747cec1 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/experimental/callOfBaseFunctionFromGeneric.kt @@ -0,0 +1,31 @@ +// FIR_IDENTICAL +// See KT-54823 + +@RequiresOptIn +annotation class Marker + +interface VeryBase { + fun foo(base: VeryBase<*>) {} +} + +@Marker +abstract class Base : VeryBase { + fun bar(base: Base<*>) {} + + fun baz() {} +} + +@OptIn(Marker::class) +open class Intermediate : Base() + +class Derived : Intermediate() + +fun main() { + val d = Derived() + // Should be Ok (declared in VeryBase without marker) + d.foo(d) + // Should be Ok (declared in Base with marker, but called on a receiver of type Derived without marker) + d.baz() + // Should be Error (has a parameter of type Base with marker) + d.bar(d) +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/experimental/callOfBaseFunctionFromGeneric.txt b/compiler/testData/diagnostics/testsWithStdLib/experimental/callOfBaseFunctionFromGeneric.txt new file mode 100644 index 00000000000..065a30a0f34 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/experimental/callOfBaseFunctionFromGeneric.txt @@ -0,0 +1,47 @@ +package + +public fun main(): kotlin.Unit + +@Marker public abstract class Base : VeryBase { + public constructor Base() + public final fun bar(/*0*/ base: Base<*>): kotlin.Unit + public final fun baz(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun foo(/*0*/ base: VeryBase<*>): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Derived : Intermediate { + public constructor Derived() + public final override /*1*/ /*fake_override*/ fun bar(/*0*/ base: Base<*>): kotlin.Unit + public final override /*1*/ /*fake_override*/ fun baz(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun foo(/*0*/ base: VeryBase<*>): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@kotlin.OptIn(markerClass = {Marker::class}) public open class Intermediate : Base { + public constructor Intermediate() + public final override /*1*/ /*fake_override*/ fun bar(/*0*/ base: Base<*>): kotlin.Unit + public final override /*1*/ /*fake_override*/ fun baz(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun foo(/*0*/ base: VeryBase<*>): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@kotlin.RequiresOptIn public final annotation class Marker : kotlin.Annotation { + public constructor Marker() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface VeryBase { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open fun foo(/*0*/ base: VeryBase<*>): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.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 52b004e60cf..7c2bd043953 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 @@ -37940,6 +37940,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/bodyUsagesAndInline.kt"); } + @Test + @TestMetadata("callOfBaseFunctionFromGeneric.kt") + public void testCallOfBaseFunctionFromGeneric() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/callOfBaseFunctionFromGeneric.kt"); + } + @Test @TestMetadata("classMembers.kt") public void testClassMembers() throws Exception {