Fix phpstan/phpstan#11314: Template of imported type breaks imported type#5360
Open
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
Open
Fix phpstan/phpstan#11314: Template of imported type breaks imported type#5360phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
Conversation
…type - When a class has both @phpstan-import-type and @template with the imported type as bound, resolving the template bound triggered a cyclic dependency in FileTypeMapper - The cycle occurred because resolving the type alias went through ClassReflection::getTypeAliases() which needed the full resolved PHPDoc, but the PHPDoc was still being built - Fix: store a partial NameScope (with type aliases but before template resolution) and return it on cycle detection instead of throwing NameScopeAlreadyBeingCreatedException - New regression test in tests/PHPStan/Analyser/nsrt/bug-11314.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When a class has both
@phpstan-import-type Breed from Catand@template T of Breedin the same PHPDoc comment, the imported type aliasBreedcould not be resolved. Properties typed with@var Breedwere incorrectly resolved tostring(the native type) instead of the imported type alias.Changes
src/Type/FileTypeMapper.phpto store a partialNameScope(with type aliases resolved but before template tag resolution) and return it when a cyclic dependency is detected duringgetNameScope(), instead of throwingNameScopeAlreadyBeingCreatedException$inProcessNameScopesfield to track partial NameScopes during resolutiontests/PHPStan/Analyser/nsrt/bug-11314.phpRoot cause
When
FileTypeMapper::getNameScope()resolves template tag bounds, it callsTypeNodeResolver::resolve()which triggers type alias resolution throughUsefulTypeAliasResolver::resolveLocalTypeAlias(). This in turn callsClassReflection::getTypeAliases(), which needsgetResolvedPhpDoc(), which calls back toFileTypeMapper::getNameScope()for the same class. The cycle detection ingetNameScope()threwNameScopeAlreadyBeingCreatedException, causinggetResolvedPhpDoc()to return an empty PHPDoc block. With empty PHPDoc,getTypeAliases()returned an empty array, so the imported type alias could not be found.The fix stores the NameScope built so far (which already has type alias information) before template resolution begins. When the cycle is detected, this partial NameScope is returned instead of throwing. This allows
ClassReflection::getTypeAliases()to correctly extract type alias information from the PHPDoc, breaking the cycle while preserving the data needed for type alias resolution.Test
Added
tests/PHPStan/Analyser/nsrt/bug-11314.phpwhich verifies thatCat2::$breed(with both@phpstan-import-typeand@template T of Breed) correctly resolves to'British Shorthair'|'Maine Coon'|'Siamese'instead ofstring.Fixes phpstan/phpstan#11314