In the below code, I see a warning no tail calls found
, but the same function, when written as extension function, doesn't have that warning. Now I am confused whether my IDE is wrong, or my Extension method is not actually tail-recursive or is there a difference between how compiler deals with Instance methods vs Extension functions.

- 1,933
- 1
- 17
- 24
-
See https://stackoverflow.com/questions/60202108/why-it-is-not-a-tail-recursion. – Alexey Romanov Apr 27 '20 at 18:38
1 Answers
As the second warning
Recursive call is not a tail call
indicates, this call is recursive, but is not a tail call.
This is because the function is being invoked with a different instance as its target (next
and not this
), so tailrec
doesn't really have an effect in this case. If you replace the target with this
, the compiler stops issuing any warnings.
I assume the extension function compiles without any warnings because they are compiled as static (i.e. non-instance) functions, where the target is simply another parameter, meaning that the transformed code looks (roughly) like
@Nullable
public static final SLLNode2 getNodeForValue2(@NotNull SLLNode2 $this$getNodeForValue2, int valToFind) {
Intrinsics.checkParameterIsNotNull($this$getNodeForValue2, "$this$getNodeForValue2");
if ($this$getNodeForValue2.getValue() == valToFind) {
return $this$getNodeForValue2;
} else {
SLLNode2 var10000 = $this$getNodeForValue2.getNext();
return var10000 != null ? getNodeForValue2(var10000, valToFind) : null;
}
}
which quite clearly contains a recursive tail call.
However, I'm not sure this distinction is intentional, since the way extension functions are compiled should be an implementation detail, and the instance function example should(?) be equivalently optimizable.
Edit: it seems this is in fact a bug.

- 13,516
- 4
- 51
- 70
-
1There is a bug to make this work on the Kotlin bug tracker, but not actively worked on :( https://stackoverflow.com/questions/60202108/why-it-is-not-a-tail-recursion – Alexey Romanov Apr 27 '20 at 18:39
-
@AlexeyRomanov thanks! I figured this might be the case. Unfortunately, these small Kotlin bugs seem to [pop](https://stackoverflow.com/questions/47737623/throws-has-no-effect-when-the-target-is-a-property) [up](https://stackoverflow.com/questions/47717542/kotlin-illegalaccesserror-with-and-for-delegated-interface/47719143#47719143) a [lot](https://stackoverflow.com/questions/48948311/retrieve-annotations-from-ktype/48948854#48948854) and tend to take a while to fix :/ – Salem Apr 27 '20 at 19:14