[FIR] Don't report TAILREC_ON_VIRTUAL_MEMBER_ERROR on private declarations

This commit is contained in:
Dmitriy Novozhilov
2022-05-13 16:24:18 +03:00
committed by teamcity
parent 399aaeca9d
commit 67589b1b09
5 changed files with 18 additions and 2 deletions
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.analysis.cfa.util.TraverseDirection
import org.jetbrains.kotlin.fir.analysis.cfa.util.traverse
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
@@ -14,6 +15,7 @@ import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.utils.isOverride
import org.jetbrains.kotlin.fir.declarations.utils.isTailRec
import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
import org.jetbrains.kotlin.fir.expressions.arguments
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
@@ -27,7 +29,7 @@ import org.jetbrains.kotlin.fir.types.toSymbol
object FirTailrecFunctionChecker : FirSimpleFunctionChecker() {
override fun check(declaration: FirSimpleFunction, context: CheckerContext, reporter: DiagnosticReporter) {
if (!declaration.isTailRec) return
if (!declaration.isEffectivelyFinal(context)) {
if (!(declaration.isEffectivelyFinal(context) || declaration.visibility == Visibilities.Private)) {
reporter.reportOn(declaration.source, FirErrors.TAILREC_ON_VIRTUAL_MEMBER_ERROR, context)
}
val graph = declaration.controlFlowGraphReference?.controlFlowGraph ?: return
@@ -100,4 +100,4 @@ interface IrTypeAbbreviation : IrAnnotationContainer {
val typeAlias: IrTypeAliasSymbol
val hasQuestionMark: Boolean
val arguments: List<IrTypeArgument>
}
}
@@ -17,6 +17,10 @@ open class A {
boo(y)
}
<!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>open<!> tailrec fun booOpen(y: Int) {
booOpen(y)
}
internal tailrec fun baa(y: Int) {
baa(y)
}
@@ -17,6 +17,10 @@ open class A {
boo(y)
}
<!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>open<!> tailrec fun booOpen(y: Int) {
booOpen(y)
}
internal tailrec fun baa(y: Int) {
baa(y)
}
@@ -8,6 +8,7 @@ public open class A {
internal open tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
protected open tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
private final tailrec fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
private open tailrec fun booOpen(/*0*/ y: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -20,6 +21,7 @@ public open class B : A {
internal final override /*1*/ tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
protected final override /*1*/ tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
invisible_fake final override /*1*/ tailrec /*fake_override*/ fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
invisible_fake open override /*1*/ tailrec /*fake_override*/ fun booOpen(/*0*/ y: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -32,6 +34,7 @@ public open class C : A {
internal open override /*1*/ tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
protected open override /*1*/ tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
invisible_fake final override /*1*/ tailrec /*fake_override*/ fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
invisible_fake open override /*1*/ tailrec /*fake_override*/ fun booOpen(/*0*/ y: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -44,6 +47,7 @@ public object D : A {
internal open override /*1*/ tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
protected open override /*1*/ tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
invisible_fake final override /*1*/ tailrec /*fake_override*/ fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
invisible_fake open override /*1*/ tailrec /*fake_override*/ fun booOpen(/*0*/ y: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -56,6 +60,7 @@ public sealed class E : A {
internal open override /*1*/ tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
protected open override /*1*/ tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
invisible_fake final override /*1*/ tailrec /*fake_override*/ fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
invisible_fake open override /*1*/ tailrec /*fake_override*/ fun booOpen(/*0*/ y: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -67,6 +72,7 @@ public sealed class E : A {
internal open override /*1*/ tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
protected open override /*1*/ tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
invisible_fake final override /*1*/ tailrec /*fake_override*/ fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
invisible_fake open override /*1*/ tailrec /*fake_override*/ fun booOpen(/*0*/ y: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int