Dead Code Elimination
debt(d3/e3/b3/t5)
Closest to 'default linter catches' (d3). PHPStan (listed in detection_hints.tools) catches dead code at level 2+, Psalm and Rector also detect unreachable branches and unused functions. These are standard static analysis tools in the PHP ecosystem that flag dead code patterns automatically.
Closest to 'simple parameterised fix' (e3). The quick_fix indicates enabling PHPStan dead code detection and using named exports — these are configuration-level changes. Removing dead code itself is typically deleting unreachable branches or unused functions, which is straightforward but may touch multiple files when cleaning up an entire codebase.
Closest to 'localised tax' (b3). Dead code imposes cognitive load on maintainers who must parse through irrelevant branches, but it's localized — each piece of dead code affects only the file/component it lives in. It doesn't create architectural gravity or cross-cutting dependencies; it's clutter that accumulates but can be incrementally removed.
Closest to 'notable trap' (t5). The misconception field explicitly states developers think dead code is just commented-out code, missing that it includes unreachable branches after return/throw, always-true conditions, and defined-but-never-called functions. This is a documented gotcha — developers learn it eventually but initially underestimate the scope of what constitutes dead code.
Also Known As
TL;DR
Explanation
Dead code elimination (DCE) operates at two levels. At the compiler level, it removes unreachable branches (after `return`, inside impossible conditions), unused variables whose computed values are never read, and pure expressions whose results are discarded. Modern JS bundlers (Webpack, Rollup, esbuild) implement tree-shaking — a module-level form of DCE that removes entire exported functions never imported by the rest of the bundle, shrinking JavaScript payloads significantly. In PHP, OPcache performs some DCE at the opcode level. Static analysers like PHPStan and Psalm detect dead code as a quality signal: unreachable code after a `return`, conditions that are always true/false, and methods that are never called. From a developer perspective, dead code increases cognitive load, misleads future readers, and can mask bugs (code left commented out or bypassed rather than deleted).
Common Misconception
Why It Matters
Common Mistakes
- Leaving `else` branches after a `return` in the `if` — the else is dead; PHPStan flags this.
- Defining constants or configuration values that are never read — clutters the codebase and can mislead.
- Using `export default` for everything in JavaScript — prevents tree shaking; named exports are required for bundlers to eliminate unused code.
- Keeping bypass flags like `if (false) { // old logic }` instead of deleting — dead code that silently rots and confuses readers.
Code Examples
// PHP dead code patterns:
function process(int $value): string {
if ($value > 0) {
return 'positive';
} else {
return 'non-positive'; // else is dead after return — always executes
}
echo 'never reached'; // dead — after both returns
}
// JS: default export blocks tree shaking
export default {
usedFn() { /* used */ },
unusedFn() { /* bundler cannot eliminate this */ }
};
// PHP: remove dead else
function process(int $value): string {
if ($value > 0) {
return 'positive';
}
return 'non-positive'; // clear — no dead else
}
// JS: named exports enable tree shaking
export function usedFn() { /* used — bundler keeps */ }
export function unusedFn() { /* never imported — bundler eliminates */ }