-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Report diagnostic on virtual tailrec function
#KT-18541 Fixed
- Loading branch information
Mikhael Bogdanov
committed
Oct 16, 2019
1 parent
8305baa
commit adae629
Showing
14 changed files
with
671 additions
and
8 deletions.
There are no files selected for viewing
10 changes: 10 additions & 0 deletions
10
compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/TailrecFunctionChecker.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. | ||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. | ||
*/ | ||
|
||
package org.jetbrains.kotlin.resolve.checkers | ||
|
||
import org.jetbrains.kotlin.config.LanguageFeature | ||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor | ||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor | ||
import org.jetbrains.kotlin.diagnostics.Errors | ||
import org.jetbrains.kotlin.psi.KtDeclaration | ||
import org.jetbrains.kotlin.psi.KtNamedFunction | ||
import org.jetbrains.kotlin.resolve.isEffectivelyFinal | ||
|
||
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 | ||
|
||
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitTailrecOnVirtualMember)) { | ||
context.trace.report(Errors.TAILREC_ON_VIRTUAL_MEMBER.on(declaration)) | ||
} else { | ||
context.trace.report(Errors.TAILREC_ON_VIRTUAL_MEMBER_ERROR.on(declaration)) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
171 changes: 171 additions & 0 deletions
171
compiler/testData/diagnostics/tests/tailRecOnVirtualMember.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
//!LANGUAGE: -ProhibitTailrecOnVirtualMember | ||
|
||
open class A { | ||
<!TAILREC_ON_VIRTUAL_MEMBER!>tailrec open fun foo(x: Int)<!> { | ||
foo(x) | ||
} | ||
|
||
<!TAILREC_ON_VIRTUAL_MEMBER!>internal tailrec open fun bar(y: Int)<!> { | ||
bar(y) | ||
} | ||
|
||
<!TAILREC_ON_VIRTUAL_MEMBER!>protected tailrec open fun baz(y: Int)<!> { | ||
baz(y) | ||
} | ||
|
||
private tailrec fun boo(y: Int) { | ||
boo(y) | ||
} | ||
|
||
internal tailrec fun baa(y: Int) { | ||
baa(y) | ||
} | ||
} | ||
|
||
open class B : A() { | ||
final tailrec override fun foo(x: Int) { | ||
foo(x) | ||
} | ||
|
||
final tailrec override fun bar(y: Int) { | ||
bar(y) | ||
} | ||
|
||
final tailrec override fun baz(y: Int) { | ||
baz(y) | ||
} | ||
} | ||
|
||
|
||
open class C : A() { | ||
<!TAILREC_ON_VIRTUAL_MEMBER!>tailrec override fun foo(x: Int)<!> { | ||
foo(x) | ||
} | ||
|
||
<!TAILREC_ON_VIRTUAL_MEMBER!>tailrec override fun bar(y: Int)<!> { | ||
bar(y) | ||
} | ||
|
||
<!TAILREC_ON_VIRTUAL_MEMBER!>tailrec override fun baz(y: Int)<!> { | ||
baz(y) | ||
} | ||
} | ||
|
||
object D : A() { | ||
tailrec override fun foo(x: Int) { | ||
foo(x) | ||
} | ||
|
||
tailrec override fun bar(y: Int) { | ||
bar(y - 1) | ||
} | ||
|
||
tailrec override fun baz(y: Int) { | ||
baz(y) | ||
} | ||
} | ||
|
||
sealed class E : A() { | ||
<!TAILREC_ON_VIRTUAL_MEMBER!>tailrec override fun foo(x: Int)<!> { | ||
foo(x) | ||
} | ||
|
||
<!TAILREC_ON_VIRTUAL_MEMBER!>tailrec override fun bar(y: Int)<!> { | ||
bar(y) | ||
} | ||
|
||
<!TAILREC_ON_VIRTUAL_MEMBER!>tailrec override fun baz(y: Int)<!> { | ||
baz(y) | ||
} | ||
|
||
class E1 : E() { | ||
tailrec override fun foo(x: Int) { | ||
foo(x) | ||
} | ||
|
||
tailrec override fun bar(y: Int) { | ||
bar(y) | ||
} | ||
|
||
tailrec override fun baz(y: Int) { | ||
baz(y) | ||
} | ||
} | ||
} | ||
|
||
enum class F { | ||
F0, | ||
F1() { | ||
tailrec override fun foo(x: Int) { | ||
foo(x) | ||
} | ||
|
||
tailrec override fun bar(y: Int) { | ||
bar(y) | ||
} | ||
|
||
tailrec override fun baz(y: Int) { | ||
baz(y) | ||
} | ||
}; | ||
|
||
<!TAILREC_ON_VIRTUAL_MEMBER!>tailrec open fun foo(x: Int)<!> { | ||
foo(x) | ||
} | ||
|
||
<!TAILREC_ON_VIRTUAL_MEMBER!>internal tailrec open fun bar(y: Int)<!> { | ||
bar(y) | ||
} | ||
|
||
<!TAILREC_ON_VIRTUAL_MEMBER!>protected tailrec open fun baz(y: Int)<!> { | ||
baz(y) | ||
} | ||
|
||
private tailrec fun boo(y: Int) { | ||
boo(y) | ||
} | ||
|
||
internal tailrec fun baa(y: Int) { | ||
baa(y) | ||
} | ||
} | ||
|
||
enum class G { | ||
|
||
G1; | ||
|
||
<!TAILREC_ON_VIRTUAL_MEMBER!>tailrec open fun foo(x: Int)<!> { | ||
foo(x) | ||
} | ||
|
||
<!TAILREC_ON_VIRTUAL_MEMBER!>internal tailrec open fun bar(y: Int)<!> { | ||
bar(y) | ||
} | ||
|
||
<!TAILREC_ON_VIRTUAL_MEMBER!>protected tailrec open fun baz(y: Int)<!> { | ||
baz(y) | ||
} | ||
|
||
private tailrec fun boo(y: Int) { | ||
boo(y) | ||
} | ||
|
||
internal tailrec fun baa(y: Int) { | ||
baa(y) | ||
} | ||
} | ||
|
||
|
||
val z = object : A() { | ||
tailrec override fun foo(x: Int) { | ||
foo(x) | ||
} | ||
|
||
tailrec override fun bar(y: Int) { | ||
bar(y) | ||
} | ||
|
||
tailrec override fun baz(y: Int) { | ||
baz(y) | ||
} | ||
} |
Oops, something went wrong.