IR: Get rid of descriptors in tailrec calls collection
Issue #KT-33279 fixed
This commit is contained in:
+6
-7
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user