IR: Get rid of descriptors in tailrec calls collection

Issue #KT-33279 fixed
This commit is contained in:
Ilya Matveev
2019-08-12 20:02:11 +07:00
parent cafe2cdb12
commit 949bb9d150
@@ -21,10 +21,9 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.types.isUnit
import org.jetbrains.kotlin.ir.util.usesDefaultArguments
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.types.typeUtil.isUnit
/**
* Collects calls to be treated as tail recursion.
@@ -63,7 +62,7 @@ fun collectTailRecursionCalls(irFunction: IrFunction): Set<IrCall> {
}
override fun visitReturn(expression: IrReturn, data: ElementKind) {
val valueKind = if (expression.returnTarget == irFunction.descriptor) {
val valueKind = if (expression.returnTargetSymbol == irFunction.symbol) {
ElementKind.TAIL_STATEMENT
} else {
ElementKind.NOT_SURE
@@ -99,18 +98,18 @@ fun collectTailRecursionCalls(irFunction: IrFunction): Set<IrCall> {
}
// Is it a recursive call?
if (expression.descriptor.original != irFunction.descriptor) {
if (expression.symbol != irFunction.symbol) {
return
}
// TODO: check type arguments
if (DescriptorUtils.isOverride(irFunction.descriptor) && expression.usesDefaultArguments()) {
if (irFunction.overriddenSymbols.isNotEmpty() && expression.usesDefaultArguments()) {
// Overridden functions using default arguments at tail call are not included: KT-4285
return
}
expression.dispatchReceiver?.let {
if (it !is IrGetValue || it.descriptor != irFunction.descriptor.dispatchReceiverParameter) {
if (it !is IrGetValue || it.symbol.owner != irFunction.dispatchReceiverParameter) {
// A tail call is not allowed to change dispatch receiver
// class C {
// fun foo(other: C) {
@@ -133,7 +132,7 @@ fun collectTailRecursionCalls(irFunction: IrFunction): Set<IrCall> {
}
body.statements.forEachIndexed { index, irStatement ->
val kind = if (index == body.statements.lastIndex && irFunction.descriptor.returnType?.isUnit() == true) {
val kind = if (index == body.statements.lastIndex && irFunction.returnType.isUnit()) {
ElementKind.TAIL_STATEMENT
} else {
ElementKind.NOT_SURE