From b24d5390a86a7055083f851e4adb28c8af6f1fa3 Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Thu, 14 Mar 2024 10:37:08 +0000 Subject: [PATCH] [FIR] Use proper `directOverriddenFunctions` fun in `FirNativeThrowsChecker` Fix false positive `INCOMPATIBLE_THROWS_OVERRIDE` ^KT-65105 Fixed Merge-request: KT-MR-14937 Merged-by: Ivan Kochurkin --- .../native/checkers/FirNativeThrowsChecker.kt | 7 ++----- .../diagnostics/nativeTests/throws.fir.kt | 12 ++++++++++++ .../testData/diagnostics/nativeTests/throws.kt | 12 ++++++++++++ .../testData/diagnostics/nativeTests/throws.txt | 15 +++++++++++++++ 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/FirNativeThrowsChecker.kt b/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/FirNativeThrowsChecker.kt index 52437a47cae..dd2f5329f4d 100644 --- a/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/FirNativeThrowsChecker.kt +++ b/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/FirNativeThrowsChecker.kt @@ -13,8 +13,8 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker +import org.jetbrains.kotlin.fir.analysis.checkers.directOverriddenFunctions import org.jetbrains.kotlin.fir.analysis.checkers.hasModifier -import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope import org.jetbrains.kotlin.fir.analysis.diagnostics.native.FirNativeErrors import org.jetbrains.kotlin.fir.containingClassLookupTag import org.jetbrains.kotlin.fir.declarations.FirDeclaration @@ -27,7 +27,6 @@ import org.jetbrains.kotlin.fir.isSubstitutionOrIntersectionOverride import org.jetbrains.kotlin.fir.references.isError import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol -import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol import org.jetbrains.kotlin.fir.types.* @@ -136,9 +135,7 @@ sealed class FirNativeThrowsChecker(mppKind: MppCheckerKind) : FirBasicDeclarati val containingClassSymbol = localFunctionSymbol.containingClassLookupTag()?.toFirRegularClassSymbol(context.session) if (containingClassSymbol != null) { - val unsubstitutedScope = containingClassSymbol.unsubstitutedScope(context) - unsubstitutedScope.processFunctionsByName(localFunctionSymbol.name) {} - val overriddenFunctions = unsubstitutedScope.getDirectOverriddenFunctions(localFunctionSymbol) + val overriddenFunctions = localFunctionSymbol.directOverriddenFunctions(context.session, context.scopeSession) if (localFunctionSymbol == function.symbol || localThrowsAnnotation == null && overriddenFunctions.isNotEmpty()) { for (overriddenFunction in overriddenFunctions) { val annotation = if (overriddenFunction.isSubstitutionOrIntersectionOverride) { diff --git a/compiler/testData/diagnostics/nativeTests/throws.fir.kt b/compiler/testData/diagnostics/nativeTests/throws.fir.kt index cf3a03be1fc..eda6db6b9b4 100644 --- a/compiler/testData/diagnostics/nativeTests/throws.fir.kt +++ b/compiler/testData/diagnostics/nativeTests/throws.fir.kt @@ -1,3 +1,5 @@ +// ISSUE: KT-65105 + // FILE: kotlin.kt package kotlin @@ -376,3 +378,13 @@ typealias ThrowableAlias = Throwable @Throws(ThrowableAlias::class) suspend fun suspendThrowsThrowableTypealias() {} + +interface Foo { + @Throws(IllegalArgumentException::class) + public fun f(data: T) {} +} + +class Bar : Foo { + @Throws(IllegalArgumentException::class) + override fun f(data: K) {} +} diff --git a/compiler/testData/diagnostics/nativeTests/throws.kt b/compiler/testData/diagnostics/nativeTests/throws.kt index c0ca419b599..acbcded3d94 100644 --- a/compiler/testData/diagnostics/nativeTests/throws.kt +++ b/compiler/testData/diagnostics/nativeTests/throws.kt @@ -1,3 +1,5 @@ +// ISSUE: KT-65105 + // FILE: kotlin.kt package kotlin @@ -376,3 +378,13 @@ typealias ThrowableAlias = Throwable @Throws(ThrowableAlias::class) suspend fun suspendThrowsThrowableTypealias() {} + +interface Foo { + @Throws(IllegalArgumentException::class) + public fun f(data: T) {} +} + +class Bar : Foo { + @Throws(IllegalArgumentException::class) + override fun f(data: K) {} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/nativeTests/throws.txt b/compiler/testData/diagnostics/nativeTests/throws.txt index 7657709847e..75ba5cdeb36 100644 --- a/compiler/testData/diagnostics/nativeTests/throws.txt +++ b/compiler/testData/diagnostics/nativeTests/throws.txt @@ -47,6 +47,14 @@ package @kotlin.Throws(exceptionClasses = {}) public fun throwsUnresolved(): kotlin.Unit public fun withLocalClass(): kotlin.Unit +public final class Bar : Foo { + public constructor Bar() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @kotlin.Throws(exceptionClasses = {kotlin.IllegalArgumentException::class}) public open override /*1*/ fun f(/*0*/ data: K): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + public interface Base0 { public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public abstract fun foo(): kotlin.Unit @@ -152,6 +160,13 @@ public final class Exception3 : kotlin.Throwable { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } +public interface Foo { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @kotlin.Throws(exceptionClasses = {kotlin.IllegalArgumentException::class}) public open fun f(/*0*/ data: T): 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 HasThrowsWithEmptyListOnOverride : Base1 { public constructor HasThrowsWithEmptyListOnOverride() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean