Skip to content

GeneratorCallNeverConsumed ​

warning native off by default PHP ≥ 5.5

Group: 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, a global or static declaration, a reference assignment, or a by-reference foreach.
  • 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

Released under the MIT License. Native rules and rules modeled on Php Inspections (EA Extended); independent clean-room implementation.