Skip to content

while-true-try: Variable might not be defined #10245

Closed

Description

@homersimpsons

Bug report

When using a try block inside a while (true), PHPStan fails to see the variable as defined.

For simple cases such as the following PHPStan correctly deduce that the variable is defined and its type:

<?php declare(strict_types = 1);

function produceInt(): int { return 1; }

while (true) {
	$a = produceInt();
	break;
}

\PHPStan\DumpType($a); // Dumped type: int

Code snippet that reproduces the problem

https://phpstan.org/r/fb9bc3ad-1256-46ae-beb5-24e918dd07f7

Expected output

<?php declare(strict_types = 1);

/**
 * @throws \Exception
 */
function produceInt(): int
{
	return 1;
}

while (true) {
	try {
		$a = produceInt();
		break;
	} catch (\Throwable) {}
}

\PHPStan\DumpType($a); // Dumped type: int

Did PHPStan help you today? Did it make you happy in any way?

I think I cannot count the amount of issues that didn't reach production thanks to PHPStan. It also helps a lot when reviewing code as I can focus on the core logic instead of the possible mistakes here and there.

Activity

  1. added this to the Easy fixes milestone on Dec 4, 2023
  2. donquixote commented on Aug 22, 2024

    @donquixote

    Similar case without try/catch: https://phpstan.org/r/2bb8d587-d9cb-4d11-b164-d6133dc87731

    function foo(int $max): void {
    	$i = 0;
    	while (true) {
    		if ($i > $max) {
    			$result = 'done';
    			break;
    		}
    		++$i;
    	}
    	print $result;  // Variable `$result` might not be defined.
    }

    The same happens with for(;;).

    The reason to use while (true) or for (;;) would be if the entry point of the loop is the wrong place for an exit condition.

  3. phpstan-bot commented on Sep 30, 2024

    @phpstan-bot
    Contributor

    @homersimpsons After the latest push in 2.0.x, PHPStan now reports different result with your code snippet:

    @@ @@
    -PHP 8.0 – 8.3 (2 errors)
    +PHP 8.0 – 8.3 (3 errors)
     ==========
     
    + 6: Function produceInt() has Exception in PHPDoc @throws tag but it's not thrown.
     18: Dumped type: mixed
     18: Variable $a might not be defined.
     
    -PHP 7.2 – 7.4 (3 errors)
    +PHP 7.2 – 7.4 (4 errors)
     ==========
     
    + 6: Function produceInt() has Exception in PHPDoc @throws tag but it's not thrown.
     15: Non-capturing catch is supported only on PHP 8.0 and later.
     18: Dumped type: mixed
     18: Variable $a might not be defined.
    Full report

    PHP 8.0 – 8.3 (3 errors)

    Line Error
    6 Function produceInt() has Exception in PHPDoc @throws tag but it's not thrown.
    18 Dumped type: mixed
    18 Variable $a might not be defined.

    PHP 7.2 – 7.4 (4 errors)

    Line Error
    6 Function produceInt() has Exception in PHPDoc @throws tag but it's not thrown.
    15 Non-capturing catch is supported only on PHP 8.0 and later.
    18 Dumped type: mixed
    18 Variable $a might not be defined.
  4. phpstan-bot commented on Mar 3, 2026

    @phpstan-bot
    Contributor

    Closed via merging phpstan/phpstan-src#5118

  5. github-actions commented on Apr 4, 2026

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

  6. locked as resolved and limited conversation to collaborators on Apr 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions