FIR checker: report tailrec problems on the keyword
FE1.0 reports it on the declaration signature. This is not ideal so we move it to the `tailrec` keyword in FIR.
This commit is contained in:
committed by
teamcityserver
parent
922ae607f6
commit
5252effb10
+2
-2
@@ -821,8 +821,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
// TODO: replace with KtParameter
|
// TODO: replace with KtParameter
|
||||||
val CANNOT_INFER_PARAMETER_TYPE by error<KtElement>()
|
val CANNOT_INFER_PARAMETER_TYPE by error<KtElement>()
|
||||||
|
|
||||||
val NO_TAIL_CALLS_FOUND by warning<KtNamedFunction>(PositioningStrategy.DECLARATION_SIGNATURE)
|
val NO_TAIL_CALLS_FOUND by warning<KtNamedFunction>(PositioningStrategy.TAILREC_MODIFIER)
|
||||||
val TAILREC_ON_VIRTUAL_MEMBER_ERROR by error<KtNamedFunction>(PositioningStrategy.DECLARATION_SIGNATURE)
|
val TAILREC_ON_VIRTUAL_MEMBER_ERROR by error<KtNamedFunction>(PositioningStrategy.TAILREC_MODIFIER)
|
||||||
val NON_TAIL_RECURSIVE_CALL by warning<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
|
val NON_TAIL_RECURSIVE_CALL by warning<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
val TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED by warning<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
|
val TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED by warning<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -107,6 +107,7 @@ enum class PositioningStrategy(private val strategy: String? = null) {
|
|||||||
NON_FINAL_MODIFIER_OR_NAME,
|
NON_FINAL_MODIFIER_OR_NAME,
|
||||||
ENUM_MODIFIER,
|
ENUM_MODIFIER,
|
||||||
FIELD_KEYWORD,
|
FIELD_KEYWORD,
|
||||||
|
TAILREC_MODIFIER,
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -442,8 +442,8 @@ object FirErrors {
|
|||||||
val FORBIDDEN_VARARG_PARAMETER_TYPE by error1<KtParameter, ConeKotlinType>(SourceElementPositioningStrategies.PARAMETER_VARARG_MODIFIER)
|
val FORBIDDEN_VARARG_PARAMETER_TYPE by error1<KtParameter, ConeKotlinType>(SourceElementPositioningStrategies.PARAMETER_VARARG_MODIFIER)
|
||||||
val VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION by error0<KtParameter>()
|
val VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION by error0<KtParameter>()
|
||||||
val CANNOT_INFER_PARAMETER_TYPE by error0<KtElement>()
|
val CANNOT_INFER_PARAMETER_TYPE by error0<KtElement>()
|
||||||
val NO_TAIL_CALLS_FOUND by warning0<KtNamedFunction>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
val NO_TAIL_CALLS_FOUND by warning0<KtNamedFunction>(SourceElementPositioningStrategies.TAILREC_MODIFIER)
|
||||||
val TAILREC_ON_VIRTUAL_MEMBER_ERROR by error0<KtNamedFunction>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
val TAILREC_ON_VIRTUAL_MEMBER_ERROR by error0<KtNamedFunction>(SourceElementPositioningStrategies.TAILREC_MODIFIER)
|
||||||
val NON_TAIL_RECURSIVE_CALL by warning0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
val NON_TAIL_RECURSIVE_CALL by warning0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
val TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED by warning0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
val TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED by warning0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
|
|
||||||
|
|||||||
+3
@@ -379,6 +379,9 @@ object LightTreePositioningStrategies {
|
|||||||
val ENUM_MODIFIER: LightTreePositioningStrategy =
|
val ENUM_MODIFIER: LightTreePositioningStrategy =
|
||||||
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.ENUM_KEYWORD))
|
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.ENUM_KEYWORD))
|
||||||
|
|
||||||
|
val TAILREC_MODIFIER: LightTreePositioningStrategy =
|
||||||
|
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.TAILREC_KEYWORD))
|
||||||
|
|
||||||
val FIELD_KEYWORD: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
|
val FIELD_KEYWORD: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
|
||||||
override fun mark(
|
override fun mark(
|
||||||
node: LighterASTNode,
|
node: LighterASTNode,
|
||||||
|
|||||||
+5
@@ -324,4 +324,9 @@ object SourceElementPositioningStrategies {
|
|||||||
LightTreePositioningStrategies.FIELD_KEYWORD,
|
LightTreePositioningStrategies.FIELD_KEYWORD,
|
||||||
PositioningStrategies.FIELD_KEYWORD
|
PositioningStrategies.FIELD_KEYWORD
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val TAILREC_MODIFIER = SourceElementPositioningStrategy(
|
||||||
|
LightTreePositioningStrategies.TAILREC_MODIFIER,
|
||||||
|
PositioningStrategies.TAILREC_MODIFIER
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -292,6 +292,9 @@ object PositioningStrategies {
|
|||||||
@JvmField
|
@JvmField
|
||||||
val ENUM_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.ENUM_KEYWORD)
|
val ENUM_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.ENUM_KEYWORD)
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val TAILREC_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.TAILREC_KEYWORD)
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val FIELD_KEYWORD: PositioningStrategy<KtBackingField> = object : DeclarationHeader<KtBackingField>() {
|
val FIELD_KEYWORD: PositioningStrategy<KtBackingField> = object : DeclarationHeader<KtBackingField>() {
|
||||||
override fun mark(element: KtBackingField): List<TextRange> {
|
override fun mark(element: KtBackingField): List<TextRange> {
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
// DONT_RUN_GENERATED_CODE: JS
|
// DONT_RUN_GENERATED_CODE: JS
|
||||||
// IGNORE_BACKEND: JS
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun noTails()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun noTails() {
|
||||||
// nothing here
|
// nothing here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ class B {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun h2(x : Any)<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun h2(x : Any) {
|
||||||
this@B.h2("no recursion") // keep vigilance
|
this@B.h2("no recursion") // keep vigilance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
// DONT_RUN_GENERATED_CODE: JS
|
// DONT_RUN_GENERATED_CODE: JS
|
||||||
// IGNORE_BACKEND: JS
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo() {
|
||||||
bar {
|
bar {
|
||||||
<!NON_TAIL_RECURSIVE_CALL!>foo<!>()
|
<!NON_TAIL_RECURSIVE_CALL!>foo<!>()
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
// DONT_RUN_GENERATED_CODE: JS
|
// DONT_RUN_GENERATED_CODE: JS
|
||||||
// IGNORE_BACKEND: JS
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo() {
|
||||||
fun bar() {
|
fun bar() {
|
||||||
<!NON_TAIL_RECURSIVE_CALL!>foo<!>()
|
<!NON_TAIL_RECURSIVE_CALL!>foo<!>()
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
// DONT_RUN_GENERATED_CODE: JS
|
// DONT_RUN_GENERATED_CODE: JS
|
||||||
// IGNORE_BACKEND: JS
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun test(counter : Int) : Int<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun test(counter : Int) : Int {
|
||||||
if (counter == 0) return 0
|
if (counter == 0) return 0
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
// DONT_RUN_GENERATED_CODE: JS
|
// DONT_RUN_GENERATED_CODE: JS
|
||||||
// IGNORE_BACKEND: JS
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun test(counter : Int) : Int<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun test(counter : Int) : Int {
|
||||||
if (counter == 0) return 0
|
if (counter == 0) return 0
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
// DONT_RUN_GENERATED_CODE: JS
|
// DONT_RUN_GENERATED_CODE: JS
|
||||||
// IGNORE_BACKEND: JS
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun test(counter : Int) : Int<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun test(counter : Int) : Int {
|
||||||
if (counter == 0) return 0
|
if (counter == 0) return 0
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
// DONT_RUN_GENERATED_CODE: JS
|
// DONT_RUN_GENERATED_CODE: JS
|
||||||
// IGNORE_BACKEND: JS
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun test(counter : Int) : Int<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun test(counter : Int) : Int {
|
||||||
if (counter == 0) return 0
|
if (counter == 0) return 0
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
Vendored
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
// DONT_RUN_GENERATED_CODE: JS
|
// DONT_RUN_GENERATED_CODE: JS
|
||||||
// IGNORE_BACKEND: JS
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun test(go: Boolean) : Unit<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun test(go: Boolean) : Unit {
|
||||||
if (!go) return
|
if (!go) return
|
||||||
try {
|
try {
|
||||||
<!TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED!>test<!>(false)
|
<!TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED!>test<!>(false)
|
||||||
|
|||||||
+1
-1
@@ -19,7 +19,7 @@ class A {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun f3(a : A)<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun f3(a : A) {
|
||||||
a.<!NON_TAIL_RECURSIVE_CALL!>f3<!>(a) // non-tail recursion, could be potentially resolved by condition if (a == this) f3() else a.f3()
|
a.<!NON_TAIL_RECURSIVE_CALL!>f3<!>(a) // non-tail recursion, could be potentially resolved by condition if (a == this) f3() else a.f3()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -2,17 +2,17 @@
|
|||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
// !DIAGNOSTICS: -UNREACHABLE_CODE
|
// !DIAGNOSTICS: -UNREACHABLE_CODE
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo1()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo1() {
|
||||||
<!NON_TAIL_RECURSIVE_CALL!>foo1<!>()
|
<!NON_TAIL_RECURSIVE_CALL!>foo1<!>()
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo2()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo2() {
|
||||||
<!NON_TAIL_RECURSIVE_CALL!>foo2<!>()
|
<!NON_TAIL_RECURSIVE_CALL!>foo2<!>()
|
||||||
val i = 1
|
val i = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo3()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo3() {
|
||||||
<!NON_TAIL_RECURSIVE_CALL!>foo3<!>()
|
<!NON_TAIL_RECURSIVE_CALL!>foo3<!>()
|
||||||
foo1()
|
foo1()
|
||||||
}
|
}
|
||||||
@@ -27,7 +27,7 @@ tailrec fun foo5() {
|
|||||||
foo4()
|
foo4()
|
||||||
}
|
}
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo6(b: Boolean)<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo6(b: Boolean) {
|
||||||
while (b) {
|
while (b) {
|
||||||
<!NON_TAIL_RECURSIVE_CALL!>foo6<!>(!b)
|
<!NON_TAIL_RECURSIVE_CALL!>foo6<!>(!b)
|
||||||
}
|
}
|
||||||
@@ -40,21 +40,21 @@ tailrec fun foo7_return() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo7_break()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo7_break() {
|
||||||
while (true) {
|
while (true) {
|
||||||
<!NON_TAIL_RECURSIVE_CALL!>foo7_break<!>()
|
<!NON_TAIL_RECURSIVE_CALL!>foo7_break<!>()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo7_continue()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo7_continue() {
|
||||||
while (true) {
|
while (true) {
|
||||||
<!NON_TAIL_RECURSIVE_CALL!>foo7_continue<!>()
|
<!NON_TAIL_RECURSIVE_CALL!>foo7_continue<!>()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo8()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo8() {
|
||||||
while (true) {
|
while (true) {
|
||||||
<!NON_TAIL_RECURSIVE_CALL!>foo8<!>()
|
<!NON_TAIL_RECURSIVE_CALL!>foo8<!>()
|
||||||
throw Exception()
|
throw Exception()
|
||||||
@@ -62,19 +62,19 @@ tailrec fun foo7_return() {
|
|||||||
foo8()
|
foo8()
|
||||||
}
|
}
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo9()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo9() {
|
||||||
<!NON_TAIL_RECURSIVE_CALL!>foo9<!>()
|
<!NON_TAIL_RECURSIVE_CALL!>foo9<!>()
|
||||||
fun bar() {}
|
fun bar() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo10()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo10() {
|
||||||
<!NON_TAIL_RECURSIVE_CALL!>foo10<!>()
|
<!NON_TAIL_RECURSIVE_CALL!>foo10<!>()
|
||||||
class Bar {
|
class Bar {
|
||||||
val i = 1
|
val i = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo11(): String<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo11(): String {
|
||||||
return "hello ${<!NON_TAIL_RECURSIVE_CALL!>foo11<!>()}"
|
return "hello ${<!NON_TAIL_RECURSIVE_CALL!>foo11<!>()}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo1()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo1() {
|
||||||
run {
|
run {
|
||||||
<!NON_TAIL_RECURSIVE_CALL!>foo1<!>()
|
<!NON_TAIL_RECURSIVE_CALL!>foo1<!>()
|
||||||
}
|
}
|
||||||
@@ -9,13 +9,13 @@
|
|||||||
fun myRun(f: () -> Unit) = f()
|
fun myRun(f: () -> Unit) = f()
|
||||||
|
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo2()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo2() {
|
||||||
myRun {
|
myRun {
|
||||||
<!NON_TAIL_RECURSIVE_CALL!>foo2<!>()
|
<!NON_TAIL_RECURSIVE_CALL!>foo2<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo3()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo3() {
|
||||||
fun bar() {
|
fun bar() {
|
||||||
<!NON_TAIL_RECURSIVE_CALL!>foo3<!>()
|
<!NON_TAIL_RECURSIVE_CALL!>foo3<!>()
|
||||||
}
|
}
|
||||||
@@ -23,14 +23,14 @@ fun myRun(f: () -> Unit) = f()
|
|||||||
}
|
}
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo4()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo4() {
|
||||||
with(this) {
|
with(this) {
|
||||||
<!NON_TAIL_RECURSIVE_CALL!>foo4<!>()
|
<!NON_TAIL_RECURSIVE_CALL!>foo4<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo5()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo5() {
|
||||||
run {
|
run {
|
||||||
return <!NON_TAIL_RECURSIVE_CALL!>foo5<!>()
|
return <!NON_TAIL_RECURSIVE_CALL!>foo5<!>()
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -1,5 +1,5 @@
|
|||||||
// FIR_IDENTICAL
|
// FIR_IDENTICAL
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo1()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo1() {
|
||||||
try {
|
try {
|
||||||
<!TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED!>foo1<!>()
|
<!TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED!>foo1<!>()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo2()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo2() {
|
||||||
try {
|
try {
|
||||||
<!TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED!>foo2<!>()
|
<!TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED!>foo2<!>()
|
||||||
foo1()
|
foo1()
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo3()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo3() {
|
||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
<!TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED!>foo3<!>()
|
<!TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED!>foo3<!>()
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo4()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo4() {
|
||||||
try {
|
try {
|
||||||
if (true) {
|
if (true) {
|
||||||
<!TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED!>foo4<!>()
|
<!TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED!>foo4<!>()
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
//!LANGUAGE: -ProhibitTailrecOnVirtualMember
|
//!LANGUAGE: -ProhibitTailrecOnVirtualMember
|
||||||
|
|
||||||
open class A {
|
open class A {
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec open fun foo(x: Int)<!> {
|
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> open fun foo(x: Int) {
|
||||||
foo(x)
|
foo(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>internal tailrec open fun bar(y: Int)<!> {
|
internal <!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> open fun bar(y: Int) {
|
||||||
bar(y)
|
bar(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>protected tailrec open fun baz(y: Int)<!> {
|
protected <!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> open fun baz(y: Int) {
|
||||||
baz(y)
|
baz(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,15 +38,15 @@ open class B : A() {
|
|||||||
|
|
||||||
|
|
||||||
open class C : A() {
|
open class C : A() {
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec override fun foo(x: Int)<!> {
|
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> override fun foo(x: Int) {
|
||||||
foo(x)
|
foo(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec override fun bar(y: Int)<!> {
|
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> override fun bar(y: Int) {
|
||||||
bar(y)
|
bar(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec override fun baz(y: Int)<!> {
|
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> override fun baz(y: Int) {
|
||||||
baz(y)
|
baz(y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,15 +66,15 @@ object D : A() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sealed class E : A() {
|
sealed class E : A() {
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec override fun foo(x: Int)<!> {
|
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> override fun foo(x: Int) {
|
||||||
foo(x)
|
foo(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec override fun bar(y: Int)<!> {
|
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> override fun bar(y: Int) {
|
||||||
bar(y)
|
bar(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec override fun baz(y: Int)<!> {
|
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> override fun baz(y: Int) {
|
||||||
baz(y)
|
baz(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,15 +109,15 @@ enum class F {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec open fun foo(x: Int)<!> {
|
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> open fun foo(x: Int) {
|
||||||
foo(x)
|
foo(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>internal tailrec open fun bar(y: Int)<!> {
|
internal <!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> open fun bar(y: Int) {
|
||||||
bar(y)
|
bar(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>protected tailrec open fun baz(y: Int)<!> {
|
protected <!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> open fun baz(y: Int) {
|
||||||
baz(y)
|
baz(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,15 +134,15 @@ enum class G {
|
|||||||
|
|
||||||
G1;
|
G1;
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec open fun foo(x: Int)<!> {
|
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> open fun foo(x: Int) {
|
||||||
foo(x)
|
foo(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>internal tailrec open fun bar(y: Int)<!> {
|
internal <!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> open fun bar(y: Int) {
|
||||||
bar(y)
|
bar(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>protected tailrec open fun baz(y: Int)<!> {
|
protected <!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> open fun baz(y: Int) {
|
||||||
baz(y)
|
baz(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,4 +168,4 @@ val z = object : A() {
|
|||||||
tailrec override fun baz(y: Int) {
|
tailrec override fun baz(y: Int) {
|
||||||
baz(y)
|
baz(y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,15 +2,15 @@
|
|||||||
//!LANGUAGE: +ProhibitTailrecOnVirtualMember
|
//!LANGUAGE: +ProhibitTailrecOnVirtualMember
|
||||||
|
|
||||||
open class A {
|
open class A {
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec open fun foo(x: Int)<!> {
|
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> open fun foo(x: Int) {
|
||||||
foo(x)
|
foo(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>internal tailrec open fun bar(y: Int)<!> {
|
internal <!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> open fun bar(y: Int) {
|
||||||
bar(y)
|
bar(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>protected tailrec open fun baz(y: Int)<!> {
|
protected <!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> open fun baz(y: Int) {
|
||||||
baz(y)
|
baz(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,15 +39,15 @@ open class B : A() {
|
|||||||
|
|
||||||
|
|
||||||
open class C : A() {
|
open class C : A() {
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec override fun foo(x: Int)<!> {
|
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> override fun foo(x: Int) {
|
||||||
foo(x)
|
foo(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec override fun bar(y: Int)<!> {
|
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> override fun bar(y: Int) {
|
||||||
bar(y)
|
bar(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec override fun baz(y: Int)<!> {
|
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> override fun baz(y: Int) {
|
||||||
baz(y)
|
baz(y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,15 +67,15 @@ object D : A() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sealed class E : A() {
|
sealed class E : A() {
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec override fun foo(x: Int)<!> {
|
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> override fun foo(x: Int) {
|
||||||
foo(x)
|
foo(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec override fun bar(y: Int)<!> {
|
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> override fun bar(y: Int) {
|
||||||
bar(y)
|
bar(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec override fun baz(y: Int)<!> {
|
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> override fun baz(y: Int) {
|
||||||
baz(y)
|
baz(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,15 +110,15 @@ enum class F {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec open fun foo(x: Int)<!> {
|
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> open fun foo(x: Int) {
|
||||||
foo(x)
|
foo(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>internal tailrec open fun bar(y: Int)<!> {
|
internal <!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> open fun bar(y: Int) {
|
||||||
bar(y)
|
bar(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>protected tailrec open fun baz(y: Int)<!> {
|
protected <!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> open fun baz(y: Int) {
|
||||||
baz(y)
|
baz(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,15 +135,15 @@ enum class G {
|
|||||||
|
|
||||||
G1;
|
G1;
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec open fun foo(x: Int)<!> {
|
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> open fun foo(x: Int) {
|
||||||
foo(x)
|
foo(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>internal tailrec open fun bar(y: Int)<!> {
|
internal <!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> open fun bar(y: Int) {
|
||||||
bar(y)
|
bar(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>protected tailrec open fun baz(y: Int)<!> {
|
protected <!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec<!> open fun baz(y: Int) {
|
||||||
baz(y)
|
baz(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,4 +168,4 @@ val z = object : A() {
|
|||||||
tailrec override fun baz(y: Int) {
|
tailrec override fun baz(y: Int) {
|
||||||
baz(y)
|
baz(y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ open class A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class B: A() {
|
class B: A() {
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec override fun foo(x: Int)<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> override fun foo(x: Int) {
|
||||||
<!NON_TAIL_RECURSIVE_CALL!>foo<!>()
|
<!NON_TAIL_RECURSIVE_CALL!>foo<!>()
|
||||||
}
|
}
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec override fun gav(y: Int, z: Int)<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> override fun gav(y: Int, z: Int) {
|
||||||
<!NON_TAIL_RECURSIVE_CALL!>gav<!>(y)
|
<!NON_TAIL_RECURSIVE_CALL!>gav<!>(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ enum class E {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
C {
|
C {
|
||||||
<!NO_TAIL_CALLS_FOUND!>override tailrec fun rec()<!> {
|
override <!NO_TAIL_CALLS_FOUND!>tailrec<!> fun rec() {
|
||||||
C.rec() // resolution goes to `E.rec`. Hence the resolved symbol is considered different from `C.rec`.
|
C.rec() // resolution goes to `E.rec`. Hence the resolved symbol is considered different from `C.rec`.
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// FIR_IDENTICAL
|
// FIR_IDENTICAL
|
||||||
class A(val a: A) {
|
class A(val a: A) {
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo1()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo1() {
|
||||||
a.<!NON_TAIL_RECURSIVE_CALL!>foo1<!>()
|
a.<!NON_TAIL_RECURSIVE_CALL!>foo1<!>()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ class A(val a: A) {
|
|||||||
foo3()
|
foo3()
|
||||||
}
|
}
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo4()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo4() {
|
||||||
with(a) {
|
with(a) {
|
||||||
<!NON_TAIL_RECURSIVE_CALL!>foo4<!>()
|
<!NON_TAIL_RECURSIVE_CALL!>foo4<!>()
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ tailrec fun String.foo2() {
|
|||||||
this.foo2()
|
this.foo2()
|
||||||
}
|
}
|
||||||
|
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun String.foo3()<!> {
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun String.foo3() {
|
||||||
with(this) {
|
with(this) {
|
||||||
<!NON_TAIL_RECURSIVE_CALL!>foo3<!>()
|
<!NON_TAIL_RECURSIVE_CALL!>foo3<!>()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ object O {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo(i: Int)<!> = if (i < 0) 0 else A.foo(i - 1)
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo(i: Int) = if (i < 0) 0 else A.foo(i - 1)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun foo(i: Int) = 42 + i
|
fun foo(i: Int) = 42 + i
|
||||||
@@ -13,5 +13,5 @@ class A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class B {
|
class B {
|
||||||
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo(i: Int)<!> = if (i < 0) 0 else O.foo(i - 1)
|
<!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo(i: Int) = if (i < 0) 0 else O.foo(i - 1)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user