Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/Type/FileTypeMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ final class FileTypeMapper
/** @var array<string, true> */
private array $inProcess = [];

/** @var array<string, NameScope> */
private array $inProcessNameScopes = [];

/** @var array<string, ResolvedPhpDocBlock> */
private array $resolvedPhpDocBlockCache = [];

Expand Down Expand Up @@ -200,6 +203,9 @@ public function getNameScope(
{
$nameScopeKey = $this->getNameScopeKey($fileName, $className, $traitName, $functionName);
if (isset($this->inProcess[$nameScopeKey])) {
if (isset($this->inProcessNameScopes[$nameScopeKey])) {
return $this->inProcessNameScopes[$nameScopeKey];
}
throw new NameScopeAlreadyBeingCreatedException();
}

Expand Down Expand Up @@ -288,6 +294,8 @@ public function getNameScope(
continue;
}

$this->inProcessNameScopes[$nameScopeKey] = $nameScope;

$templateTags = $this->phpDocNodeResolver->resolveTemplateTags($parent->getTemplatePhpDocNodes(), $nameScope);
$templateTypeMap = new TemplateTypeMap(array_map(static fn (TemplateTag $tag): Type => TemplateTypeFactory::fromTemplateTag($templateTypeScope, $tag), $templateTags));
$nameScope = $nameScope->withTemplateTypeMap($templateTypeMap, $templateTags);
Expand Down Expand Up @@ -319,6 +327,7 @@ public function getNameScope(
);
} finally {
unset($this->inProcess[$nameScopeKey]);
unset($this->inProcessNameScopes[$nameScopeKey]);
}
}

Expand Down
51 changes: 51 additions & 0 deletions tests/PHPStan/Analyser/nsrt/bug-11314.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php declare(strict_types = 1);
Comment thread
staabm marked this conversation as resolved.

namespace Bug11314;

use function PHPStan\Testing\assertType;

/**
* @phpstan-type Breed 'Siamese'|'British Shorthair'|'Maine Coon'
*/
class Cat
{
/**
* @var Breed
*/
public string $breed;
}

/**
* @phpstan-import-type Breed from Cat
*
* @template T of Breed
*/
class Cat2
{
/**
* @var Breed
*/
public string $breed;
}

/**
* @phpstan-import-type Breed from Cat
*/
class Cat3
{
/**
* @var Breed
*/
public string $breed;
}

function () {
$cat = new Cat();
assertType("'British Shorthair'|'Maine Coon'|'Siamese'", $cat->breed);

$cat2 = new Cat2();
assertType("'British Shorthair'|'Maine Coon'|'Siamese'", $cat2->breed);

$cat3 = new Cat3();
assertType("'British Shorthair'|'Maine Coon'|'Siamese'", $cat3->breed);
};
Loading