Redundant Suspend

ID

kotlin.redundant_suspend

Severity

low

Remediation Complexity

medium

Remediation Risk

low

Remediation Effort

medium

Resource

Code Smell

Language

Kotlin

Tags

code-style, concurrency

Description

Reports functions declared suspend whose body cannot possibly invoke any suspending function. The suspend modifier is meaningful only when the body actually suspends (calls another suspend function, a coroutine primitive, or a flow terminal operator). A suspend function whose body is a pure expression cannot suspend; the modifier is pure overhead and forces every caller to be suspend-aware for nothing.

Rationale

// Bad — body cannot suspend
suspend fun compute(x: Int): Int = x * 2

suspend fun greet(): String {
    return "hi"
}

The compiler still threads continuation plumbing through these functions, and every caller has to be inside a coroutine to invoke them. The result is API noise without any benefit.

Remediation

Drop the suspend modifier. If the function is part of an interface whose other members are suspending, leave it as is — the modifier may be a contract choice rather than a smell.

fun compute(x: Int): Int = x * 2
fun greet(): String = "hi"

Exceptions

Detection is intentionally conservative — without full semantic typing the rule cannot tell whether an arbitrary foo() call is suspending. It only fires when the body has zero function calls and zero member-navigation expressions, which is the strongest signal that the body cannot possibly invoke a suspending function. Overrides, abstract, expect, and external functions are skipped.