diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/TailrecFunctionChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/TailrecFunctionChecker.kt index 129403b4dad..4127ee3c3a5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/TailrecFunctionChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/TailrecFunctionChecker.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.resolve.checkers import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.psi.KtDeclaration @@ -16,7 +17,8 @@ object TailrecFunctionChecker : DeclarationChecker { override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) { if (declaration !is KtNamedFunction || descriptor !is FunctionDescriptor || !descriptor.isTailrec) return - if (descriptor.isEffectivelyFinal(false)) return + // Private check is needed for opened private functions by allopen plugin (see KT-48117) + if (descriptor.isEffectivelyFinal(false) || DescriptorVisibilities.isPrivate(descriptor.visibility)) return context.trace.report(Errors.TAILREC_ON_VIRTUAL_MEMBER.on(context.languageVersionSettings, declaration)) } diff --git a/plugins/allopen/allopen-cli/testData/bytecodeListing/privateMembers.kt b/plugins/allopen/allopen-cli/testData/bytecodeListing/privateMembers.kt index 33668e5fcbb..e22039a07b7 100644 --- a/plugins/allopen/allopen-cli/testData/bytecodeListing/privateMembers.kt +++ b/plugins/allopen/allopen-cli/testData/bytecodeListing/privateMembers.kt @@ -13,4 +13,6 @@ private class Test { internal fun internalMethod() {} internal val internalProp: String = "" + + private tailrec fun privateTailrecMethod() {} } \ No newline at end of file diff --git a/plugins/allopen/allopen-cli/testData/bytecodeListing/privateMembers.txt b/plugins/allopen/allopen-cli/testData/bytecodeListing/privateMembers.txt index 832296ab5da..cc61263f2d4 100644 --- a/plugins/allopen/allopen-cli/testData/bytecodeListing/privateMembers.txt +++ b/plugins/allopen/allopen-cli/testData/bytecodeListing/privateMembers.txt @@ -1,4 +1,4 @@ -@java.lang.annotation.Retention +@java.lang.annotation.Retention(value=RUNTIME) @kotlin.Metadata public annotation class AllOpen { // source: 'privateMembers.kt' @@ -18,6 +18,7 @@ class Test { public @org.jetbrains.annotations.NotNull method getPublicProp(): java.lang.String public method internalMethod$test_module(): void private method privateMethod(): void + private method privateTailrecMethod(): void protected method protectedMethod(): void public method publicMethod(): void } diff --git a/plugins/allopen/allopen-cli/testData/bytecodeListing/privateMembers_ir.txt b/plugins/allopen/allopen-cli/testData/bytecodeListing/privateMembers_ir.txt index 03f08be40e7..36ba4085ff0 100644 --- a/plugins/allopen/allopen-cli/testData/bytecodeListing/privateMembers_ir.txt +++ b/plugins/allopen/allopen-cli/testData/bytecodeListing/privateMembers_ir.txt @@ -1,4 +1,4 @@ -@java.lang.annotation.Retention +@java.lang.annotation.Retention(value=RUNTIME) @kotlin.Metadata public annotation class AllOpen { // source: 'privateMembers.kt' @@ -6,7 +6,7 @@ public annotation class AllOpen { @AllOpen @kotlin.Metadata -final class Test { +class Test { // source: 'privateMembers.kt' private final @org.jetbrains.annotations.NotNull field internalProp: java.lang.String private final @org.jetbrains.annotations.NotNull field privateProp: java.lang.String @@ -17,8 +17,8 @@ final class Test { protected @org.jetbrains.annotations.NotNull method getProtectedProp(): java.lang.String public @org.jetbrains.annotations.NotNull method getPublicProp(): java.lang.String public method internalMethod$test_module(): void - private final method privateMethod(): void - private final method privateTailrecMethod(): void + private method privateMethod(): void + private method privateTailrecMethod(): void protected method protectedMethod(): void public method publicMethod(): void }