mago icon indicating copy to clipboard operation
mago copied to clipboard

feature request: Detect unreachable else clause when all enum cases are handled

Open bendavies opened this issue 4 months ago • 2 comments

🐞 Describe the Bug

Mago does not detect unreachable code when an if-elseif-else chain handles all possible enum values. When an enum has a finite set of values and all are explicitly checked, the final else clause is unreachable and should be reported as dead code.

🔄 Steps to Reproduce

  1. Create an enum with a finite set of values (e.g., 3 cases)
  2. Write an if-elseif-else chain that checks all enum values explicitly
  3. Add an else clause with code (e.g., throwing an exception)
  4. Run mago analyse on the file
  5. Mago does not report any issue
  6. Expected: Mago should report that the else clause is unreachable since all enum cases are handled

⚙️ Configuration (mago.toml)

# Mago configuration file
# For more information, see https://mago.carthage.software/#/getting-started/configuration
php-version = "8.3.0"

[source]
paths = ["config/", "src/", "migrations/"]
includes = ["vendor"]
excludes = ["src/BindHQ/Bundle/TestsBundle/Resources/LoadSystemDataReferences.php"]

[formatter]
print-width = 180
tab-width = 4
use-tabs = false
null-type-hint = "question"
always-break-named-arguments-list = false
preserve-breaking-argument-list = true
preserve-breaking-array-like = true
preserve-breaking-attribute-list = true
preserve-breaking-conditional-expression = true
preserve-breaking-member-access-chain = true
preserve-breaking-parameter-list = true

[linter]
integrations = ["symfony", "php-unit"]

[analyzer]
mixed-issues = false
ignore = ["non-existent-method"]

📜 Command Output

# Currently no output - Mago does not detect this issue
# Expected output would be something like:
warning[unreachable-code]: This else clause is unreachable because all enum cases are handled
   ┌─ src/Example.php:10:13
   │
10 │             } else {
   │               ^^^^ All cases of TemplateFillableUsage are already handled
   │
   = The enum TemplateFillableUsage has 3 cases: AVAILABLE, UNAVAILABLE, CUSTOM
   = All cases are explicitly checked in the preceding if-elseif conditions
   = Help: Remove this unreachable else clause or use a match expression for exhaustive checking

📂 PHP Code Sample

<?php

enum TemplateFillableUsage
{
    case AVAILABLE;
    case UNAVAILABLE;
    case CUSTOM;
    
    public function getReadable(): string
    {
        return match($this) {
            self::AVAILABLE => 'Available',
            self::UNAVAILABLE => 'Unavailable',
            self::CUSTOM => 'Custom',
        };
    }
}

class TemplateHandler
{
    public function processUsage(TemplateFillableUsage $usage): void
    {
        if (TemplateFillableUsage::AVAILABLE === $usage) {
            // Handle available case
            $this->handleAvailable();
        } elseif (TemplateFillableUsage::UNAVAILABLE === $usage) {
            // Handle unavailable case
            $this->handleUnavailable();
        } elseif (TemplateFillableUsage::CUSTOM === $usage) {
            // Handle custom case
            $this->handleCustom();
        } else {
            // This else block is unreachable since all enum cases are handled
            throw new \RuntimeException(Str\format('Unknown template usage: %s.', $usage->getReadable()));
        }
    }
}

🖥️ Operating System

macOS

📦 How did you install Mago?

Composer (composer require carthage-software/mago)

bendavies avatar Sep 02 '25 16:09 bendavies

Mago already highlights that the previous condition is always true, and is redundant, not sure what value would highlight the else branch add here 🤔

Image

azjezz avatar Sep 04 '25 04:09 azjezz

i thought to report that it is un reachable

bendavies avatar Sep 04 '25 12:09 bendavies