6666use PHPStan \Type \TypeUtils ;
6767use PHPStan \Type \TypeWithClassName ;
6868use PHPStan \Type \UnionType ;
69+ use function array_key_exists ;
6970use function array_keys ;
7071use function array_merge ;
7172use function assert ;
7980use function is_int ;
8081use function max ;
8182use function min ;
83+ use function sprintf ;
8284use function strtolower ;
8385use const INF ;
8486
@@ -87,6 +89,9 @@ class InitializerExprTypeResolver
8789
8890 public const CALCULATE_SCALARS_LIMIT = 128 ;
8991
92+ /** @var array<string, true> */
93+ private array $ currentlyResolvingClassConstant = [];
94+
9095 public function __construct (
9196 private ConstantResolver $ constantResolver ,
9297 private ReflectionProviderProvider $ reflectionProviderProvider ,
@@ -1876,9 +1881,18 @@ function (Type $type, callable $traverse): Type {
18761881 continue ;
18771882 }
18781883
1884+ $ resolvingName = sprintf ('%s::%s ' , $ constantClassReflection ->getName (), $ constantName );
1885+ if (array_key_exists ($ resolvingName , $ this ->currentlyResolvingClassConstant )) {
1886+ $ types [] = new MixedType ();
1887+ continue ;
1888+ }
1889+
1890+ $ this ->currentlyResolvingClassConstant [$ resolvingName ] = true ;
1891+
18791892 if (!$ isObject ) {
18801893 $ reflectionConstant = $ constantClassReflection ->getNativeReflection ()->getReflectionConstant ($ constantName );
18811894 if ($ reflectionConstant === false ) {
1895+ unset($ this ->currentlyResolvingClassConstant [$ resolvingName ]);
18821896 continue ;
18831897 }
18841898 $ reflectionConstantDeclaringClass = $ reflectionConstant ->getDeclaringClass ();
@@ -1893,6 +1907,7 @@ function (Type $type, callable $traverse): Type {
18931907 $ constantType ,
18941908 $ nativeType ,
18951909 );
1910+ unset($ this ->currentlyResolvingClassConstant [$ resolvingName ]);
18961911 continue ;
18971912 }
18981913
@@ -1903,6 +1918,7 @@ function (Type $type, callable $traverse): Type {
19031918 && !$ constantReflection ->hasPhpDocType ()
19041919 && !$ constantReflection ->hasNativeType ()
19051920 ) {
1921+ unset($ this ->currentlyResolvingClassConstant [$ resolvingName ]);
19061922 return new MixedType ();
19071923 }
19081924
@@ -1925,6 +1941,7 @@ function (Type $type, callable $traverse): Type {
19251941 $ constantType ,
19261942 $ nativeType ,
19271943 );
1944+ unset($ this ->currentlyResolvingClassConstant [$ resolvingName ]);
19281945 $ types [] = $ constantType ;
19291946 }
19301947
0 commit comments