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.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.expressions.* 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.util.usesDefaultArguments
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor 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. * 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) { override fun visitReturn(expression: IrReturn, data: ElementKind) {
val valueKind = if (expression.returnTarget == irFunction.descriptor) { val valueKind = if (expression.returnTargetSymbol == irFunction.symbol) {
ElementKind.TAIL_STATEMENT ElementKind.TAIL_STATEMENT
} else { } else {
ElementKind.NOT_SURE ElementKind.NOT_SURE
@@ -99,18 +98,18 @@ fun collectTailRecursionCalls(irFunction: IrFunction): Set<IrCall> {
} }
// Is it a recursive call? // Is it a recursive call?
if (expression.descriptor.original != irFunction.descriptor) { if (expression.symbol != irFunction.symbol) {
return return
} }
// TODO: check type arguments // 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 // Overridden functions using default arguments at tail call are not included: KT-4285
return return
} }
expression.dispatchReceiver?.let { 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 // A tail call is not allowed to change dispatch receiver
// class C { // class C {
// fun foo(other: C) { // fun foo(other: C) {
@@ -133,7 +132,7 @@ fun collectTailRecursionCalls(irFunction: IrFunction): Set<IrCall> {
} }
body.statements.forEachIndexed { index, irStatement -> 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 ElementKind.TAIL_STATEMENT
} else { } else {
ElementKind.NOT_SURE ElementKind.NOT_SURE