GeneratorCallNeverConsumed
warning native off by default PHP ≥ 5.5Group: Probable bugs
Detect a standalone discarded call to a resolved project callable containing yield and at least one deferred side-effect operation.
Example
php
<?php
function deliver() { yield sendPacket(); } deliver();Reported:
- line 2: Consume the generator to execute its body.
Detection
- Report a standalone discarded call to a resolved project callable containing yield and at least one deferred side-effect operation.
- Deferred side-effect operations are those owned by the generator body itself (nested functions, closures and classes are skipped): function, method and static calls, object creation,
echo,print, inline HTML,include/require,eval,exit/die,throw, and assignments or increments whose target is not a plain local variable (property, static property,$GLOBALS, dynamic variable or destructuring targets). - A write to a named local variable (
$x = ...,$x[...] = ...,$x++) is not observable outside the generator and does not count on its own. It counts only when the body may alias a local to outer state: a by-reference parameter, aglobalorstaticdeclaration, a reference assignment, or a by-referenceforeach. - Resolve builtin calls and named arguments before checking the contract. Project-local callees are considered only when their bodies or immutable summaries establish the required facts. The default is disabled; enable only when the stated intent matches the application.
- For flow-dependent conditions, require a reachable source-to-use path with no intervening invalidation. Unknown calls, ambiguous aliases, recursion or analysis-budget exhaustion cannot establish definite facts.
Exceptions (no report)
- Calls assigned, returned, iterated, delegated with yield from, or passed to another callable are excluded.
- First-class callable syntax
f(...)creates a Closure and calls nothing, so there is no generator to consume. - Unresolved targets, incomplete required facts, suppressed findings and PHP versions lacking the referenced API or language feature produce no report. User declarations shadowing builtin names are not builtin contracts.
Fix
No automatic fix: consuming a generator can be unbounded and removing yield changes its interface.
PHP versions
Available from PHP 5.5. Builtin behavior and argument contracts follow the configured PHP version. Extension-specific calls require resolved extension API symbols; do not treat same-named application functions as extension calls.
Options
None. Enable or disable this rule through normal rule configuration.
Configure
In custos.json:
json
{
"rules": {
"GeneratorCallNeverConsumed": {
"enabled": true
}
}
}Suppress
Before the statement or declaration (or the first statement of the file):
php
// @custos-ignore GeneratorCallNeverConsumed