Skip to content

Infinite recursion on a backed enum case whose value reads its own value #15458

Closed
phpstan/phpstan-src
#6731

Description

@SanderMuller

Bug report

PHPStan does not finish on this file:

<?php

enum E: string
{
	case A = self::A->value;
}

With the Turbo extension (2.3.1 installed through Composer), the run stops after about 2 seconds with an internal error:

Internal error: Maximum call stack size of 8339456 bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion? while analysing file

Without the Turbo extension, the recursion continues until the worker reaches the PHP memory limit. With memory_limit=1G, the 2.3.x branch stops after 4 seconds with "PHPStan process crashed because it reached configured PHP memory limit: 1G". With memory_limit=-1, I stopped the 2.0.0, 2.1.30, 2.2.17 and 2.3.1 phars after 40 seconds. After 8 seconds, a --debug run of 2.3.x had a call stack of about 2 million frames. An int backed enum and two cases that read each other (case A = self::B->value; case B = self::A->value;) behave the same.

The stack repeats these four frames:

InitializerExprTypeResolver::getType()          (PropertyFetch, InitializerExprTypeResolver.php:511)
ObjectType::getInstanceProperty()
EnumCaseObjectType::getUnresolvedInstancePropertyPrototype()
ClassReflection::getEnumCase()                  (resolves the value expression again, ClassReflection.php:1083)

EnumSanityRule starts it. For a class constant, InitializerExprTypeResolver has the currentlyResolvingClassConstant guard, so const A = self::A; returns mixed. The enum case path has no such guard.

PHP rejects the code at runtime with Cannot declare self-referencing constant self::A.

Code snippet that reproduces the problem

The snippet is at the top of this report. I could not create a playground link: https://api.phpstan.org/analyse returns Internal server error for this code. The same request with case A = 'a'; returns a normal result.

Expected output

The analysis finishes, as it does for const A = self::A;. PHPStan could also report the self-reference, but it does not do that for the class constant either.

Activity

  1. mergeable commented on Oct 11, 2026

    @mergeable

    This bug report is missing a link to reproduction at phpstan.org/try.

    It will most likely be closed after manual review.

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

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions