Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[PHPDoc] Fix various PHPDoc syntax errors#62317

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
yoeunes wants to merge1 commit intosymfony:7.4
base:7.4
Choose a base branch
Loading
fromyoeunes:phpdoc-syntax-fixes-7.4

Conversation

@yoeunes
Copy link
Contributor

QA
Branch?7.4
Bug fix?no
New feature?no
BC breaks?no
Deprecations?no
Issuesn/a
LicenseMIT

This PR fixes several minor PHPDoc syntax errors

@carsonbotcarsonbot added this to the7.4 milestoneNov 5, 2025
@yoeunes
Copy link
ContributorAuthor

hi@nicolas-grekas this PR target 7.4 instead of this one#62316

* @param U|null $backingType
*
* @return ($className is class-string<\BackedEnum> ? ($backingType is U ? BackedEnumType<T, U> : BackedEnumType<T, BuiltinType<TypeIdentifier::INT>|BuiltinType<TypeIdentifier::STRING>>) : EnumType<T>))
* @return ($className is class-string<\BackedEnum> ? ($backingType is U ? BackedEnumType<class-string<\BackedEnum>, U> : BackedEnumType<class-string<\BackedEnum>, BuiltinType<TypeIdentifier::INT>|BuiltinType<TypeIdentifier::STRING>>) : EnumType<T>)
Copy link
Member

@stofstofNov 5, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

why this change that stops usingT ?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Hi@stof, this change fixes several static analysis errors reported by Psalm.

The root cause is anInvalidTemplateParam error: the@template T is defined asUnitEnum|BackedEnum, but thetrue branch of the conditional return was passing this genericT toBackedEnumType, which strictly expectsclass-string<BackedEnum>.

This PR replaces the genericT with the more specificclass-string<\BackedEnum> in that branch, which satisfies the template constraint and resolves the subsequentInvalidReturnType errors.

Here is the full output from Psalm for reference:

https://github.com/symfony/symfony/actions/runs/19110924189

Psalm Error LogInvalidReturnType: src/Symfony/Component/TypeInfo/TypeFactoryTrait.php:239:16: InvalidReturnType: The declared return type 'Symfony\Component\TypeInfo\Type\BackedEnumType, Symfony\Component\TypeInfo\Type\BuiltinType|Symfony\Component\TypeInfo\Type\BuiltinType>|Symfony\Component\TypeInfo\Type\BackedEnumType, U:fn-symfony\component\typeinfo\typefactorytrait::enum as Symfony\Component\TypeInfo\Type\BuiltinType|Symfony\Component\TypeInfo\Type\BuiltinType>|(Symfony\Component\TypeInfo\Type\EnumType>)' for Symfony\Component\TypeInfo\TypeFactoryTrait::enum is incorrect, got 'Symfony\Component\TypeInfo\Type\BackedEnumType, TGeneratedFromParam1:fn-symfony\component\typeinfo\typefactorytrait::enum as U:fn-symfony\component\typeinfo\typefactorytrait::enum as Symfony\Component\TypeInfo\Type\BuiltinType|Symfony\Component\TypeInfo\Type\BuiltinType|null>|(Symfony\Component\TypeInfo\Type\EnumType>)' (see https://psalm.dev/011)

InvalidTemplateParam: src/Symfony/Component/TypeInfo/TypeFactoryTrait.php:239:16: InvalidTemplateParam: Extended template param T of Symfony\Component\TypeInfo\Type\BackedEnumType<T:fn-symfony\component\typeinfo\typefactorytrait::enum as class-string, U:fn-symfony\component\typeinfo\typefactorytrait::enum as Symfony\Component\TypeInfo\Type\BuiltinType<enum(Symfony\Component\TypeInfo\TypeIdentifier::INT)>|Symfony\Component\TypeInfo\Type\BuiltinType<enum(Symfony\Component\TypeInfo\TypeIdentifier::STRING)>> expects type class-string, type T:fn-symfony\component\typeinfo\typefactorytrait::enum as class-string given (seehttps://psalm.dev/183)

InvalidTemplateParam: src/Symfony/Component/TypeInfo/TypeFactoryTrait.php:239:16: InvalidTemplateParam: Extended template param T of Symfony\Component\TypeInfo\Type\BackedEnumType<T:fn-symfony\component\typeinfo\typefactorytrait::enum as class-string, Symfony\Component\TypeInfo\Type\BuiltinType<enum(Symfony\Component\TypeInfo\TypeIdentifier::INT)>|Symfony\Component\TypeInfo\Type\BuiltinType<enum(Symfony\Component\TypeInfo\TypeIdentifier::STRING)>> expects type class-string, type T:fn-symfony\component\typeinfo\typefactorytrait::enum as class-string given (seehttps://psalm.dev/183)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

but this leads to a less precise type thanT.

Maybe the conditional type should use a check onT instead of$className for the analysis to work.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Hi@stof, that's a much more elegant solution. You're right, checkingT directly instead of$className should allow the static analysis to work while preserving the type precision.

I've pushed the change. Thanks 🙏🏼

Copy link
ContributorAuthor

@yoeunesyoeunesNov 5, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Hi@stof, I tried checkingT directly in the conditional, but unfortunately, Psalm still reports the exact sameInvalidTemplateParam errors.

It seems the analyzer is unable to "narrow" the type ofT (fromUnitEnum) based on that conditional.

I've reverted to my original fix (using theclass-string<\BackedEnum>) and pushed that.

Let me know if that's okay, or if you'd prefer a different approach. Thanks!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@yoeunes are you looking at what Psalm is able to do when analyzing the code of that method, or when analyzing codecalling that method ?
The second case is more important for the value it brings to the ecosystem (and it might make sense to also check how phpstan analyzes such caller code, as projects using Symfony might use any tool).

I know that psalm is not always smart enough to analyze code of a method that combines both conditional types and generics.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Hi@stof, that's a great point, and you're right, the "caller" analysis is the most important one.

I've tested both scenarios, and this is where it gets tricky:

  1. Internal Analysis (CI): Your suggestion to check(T is ...) is the most elegant, but as the CI run showed,Psalm still fails. It reports the sameInvalidTemplateParam error, as it seems unable to "narrow" the genericT (fromUnitEnum) inside the conditional.

  2. Caller Analysis (User-land): To fix that Psalm error, I first tried the "less precise" workaround (BackedEnumType<class-string<\BackedEnum>, ...>). This fixes Psalm, but it then causesPHPStan to fail forcallers with anUnable to resolve the template type U error. This happens when a user calls::enum() with only one argument (ornull), as PHPStan can't inferU.

I've finally pushed a solution that makesboth analyzers happy. It's the one in the PR now, which combines the two fixes:

  1. It usesBackedEnumType<class-string<\BackedEnum>, ... to satisfyPsalm's internal analysis.
  2. It adds aninner conditional check for($backingType is null ? ...) to satisfyPHPStan's caller analysis (by giving it a concrete type path whenU cannot be inferred).

This final version now passes all tests, both inside Symfony's CI and when analyzing user-land code.

Here is the simple user-land script I used to reproduce and fix the PHPStan (caller) error:

<?phprequire__DIR__.'/vendor/autoload.php';useSymfony\Component\TypeInfo\TypeFactoryTrait;enum MyEnum:string {case A ='a';}class TestEnumType{use TypeFactoryTrait;}// This call (with 1 arg) triggers "Unable to resolve U"// unless the PHPDoc has the inner ($backingType is null) check.TestEnumType::enum(MyEnum::class);

Let me know if this solution looks good. Thanks!

@yoeunesyoeunesforce-pushed thephpdoc-syntax-fixes-7.4 branch 4 times, most recently from51e77aa to4af7f20CompareNovember 5, 2025 21:48
@yoeunesyoeunesforce-pushed thephpdoc-syntax-fixes-7.4 branch from4af7f20 to827ad60CompareNovember 6, 2025 01:04
* $className is class-string<\BackedEnum>
* ? ($backingType is null
* ? BackedEnumType<class-string<\BackedEnum>, BuiltinType<TypeIdentifier::INT>|BuiltinType<TypeIdentifier::STRING>>
* : BackedEnumType<class-string<\BackedEnum>, U>)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

this still looses the preciseT type for theBackedEnumType AFAICT.

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@stofstofstof left review comments

Assignees

No one assigned

Projects

None yet

Milestone

7.4

Development

Successfully merging this pull request may close these issues.

3 participants

@yoeunes@stof@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp