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

fix: update template annotations to remove covariant keyword #663

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
deadLocks21 wants to merge 1 commit into phpstan:2.0.x
base: 2.0.x
Choose a base branch
Loading
from deadLocks21:fix/phpstan-errors-on-class-metadata-covariant-error

Conversation

Copy link

@deadLocks21 deadLocks21 commented Jun 3, 2025
edited
Loading

Description

This PR addresses PHPStan errors related to template type variance in Doctrine's metadata classes. The errors were occurring because the template type T was declared as covariant but was being used in an invariant position in the getReflectionClass() method.

The Problem

The following errors were reported by PHPStan:

  • Template type T is declared as covariant, but occurs in invariant position in return type of method Doctrine\ODM\MongoDB\Mapping\ClassMetadata::getReflectionClass()
  • Template type T is declared as covariant, but occurs in invariant position in return type of method Doctrine\ORM\Mapping\ClassMetadataInfo::getReflectionClass()
  • Template type T is declared as covariant, but occurs in invariant position in return type of method Doctrine\Persistence\Mapping\ClassMetadata::getReflectionClass()

The Solution

We removed the -covariant modifier from the template type declarations in:

  • MongoClassMetadataInfo.stub
  • ORM/Mapping/ClassMetadata.stub
  • ORM/Mapping/ClassMetadataInfo.stub
  • Persistence/Mapping/ClassMetadata.stub

Why This Works

The covariance modifier was inappropriate in this case because:

  1. The getReflectionClass() method returns a ReflectionClass<T>
  2. This return type must be exactly of the specified type, not a subtype or supertype
  3. When a type parameter is used in an invariant position (like a return type), it should not be declared as covariant

Issues

#646

mroeling, alexblanc-evaneos, and simshaun reacted with heart emoji
Copy link

What is the expected moment to have this merged please? We want to upgrade to php8.4 but this is a blocking issue!

Copy link
Member

@mroeling Please describe what error are you experiencing and why it's blocking you from upgrading to 8.4. It'd be helpful in helping me underseand why this change is needed.

Copy link

mroeling commented Aug 27, 2025
edited
Loading

@mroeling Please describe what error are you experiencing and why it's blocking you from upgrading to 8.4. It'd be helpful in helping me understand why this change is needed.

Ofc, no problem.
Running phpstan on our code raises errors causing phpStan to fail.

Info:
phpstan level 4
Ubuntu 24.04 LTS
php 8.4.11

Line deploy/app/vendor/phpstan/phpstan-doctrine/stubs/MongoClassMetadataInfo.stub 
 ------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
 40 Template type T is declared as covariant, but occurs in invariant position in return type of method Doctrine\ODM\MongoDB\Mapping\ClassMetadata::getReflectionClass(). 
 ------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
 ------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
 Line deploy/app/vendor/phpstan/phpstan-doctrine/stubs/ORM/Mapping/ClassMetadataInfo.stub 
 ------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
 59 Template type T is declared as covariant, but occurs in invariant position in return type of method Doctrine\ORM\Mapping\ClassMetadataInfo::getReflectionClass(). 
 ------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
 ------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
 Line deploy/app/vendor/phpstan/phpstan-doctrine/stubs/Persistence/Mapping/ClassMetadata.stub 
 ------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
 20 Template type T is declared as covariant, but occurs in invariant position in return type of method Doctrine\Persistence\Mapping\ClassMetadata::getReflectionClass(). 
 ------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
 [ERROR] Found 3 errors

So basically we are waiting for this change to get into the mainstream so that we can test with php8.4. Using php8.4-fpm there is no issue, but for CLI this is blocking.
For comparison, cli php8.3 does not raise errors (obviously).

Copy link
Member

Please show the path where you're running PHPStan from, the path to bin/phpstan. There is something atypical about your setup. These errors from vendor stubs are usually filtered and not showed.

Copy link

mroeling commented Aug 27, 2025
edited
Loading

We use phing as "executor".

From the root (=phing.dir), the vendor map is in deploy/app/vendor
phpstan is run as deploy/app/vendor/bin/phpstan analyze

 <property name="phpStanBinary"
 value="${phing.dir}/deploy/app/vendor/bin/phpstan"
 override="no"/>
 
 <exec executable="${phpStanBinary}"
 passthru="true"
 checkreturn="true"
 dir="${phing.dir}"
 >
 <arg value="analyze"/>
 <arg line="--memory-limit 2G"/>
 <arg line="--no-progress"/>
 <arg path="${phing.dir}/deploy/app/include"/>
 <arg path="${phing.dir}/deploy/app/config"/>
 <arg path="${phing.dir}/deploy/app/services"/>
 <arg path="${phing.dir}/tests"/>
 </exec>

The getReflectionClass() functions from these 3 Doctrine classes are called within our codebase, in the deploy/app/include folder

Copy link
Member

That looks okay. Personally I'd try this:

 
 <exec executable="vendor/bin/phpstan"
 passthru="true"
 checkreturn="true"
 dir="${phing.dir}/deploy/app"
 >
 <arg value="analyze"/>
 <arg line="--memory-limit 2G"/>
 <arg line="--no-progress"/>
 <arg path="include"/>
 <arg path="config"/>
 <arg path="services"/>
 <arg path="tests"/>
 </exec>

Typically people don't run PHPStan with these absolute paths and that might be throwing off the filtering logic.

These bug(s) still need to be fixed, I just want to help you meanwhile.

Copy link

These bug(s) still need to be fixed, I just want to help you meanwhile.

Much appreciated! I'll give it a try.

Copy link
Contributor

This is maybe not the right way to solve this since in the original repository, there is the covariant annotation
https://github.com/doctrine/mongodb-odm/blob/e3352c0783886e525d2b8accb8bc7984148017bf/lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php#L272

But you'll see there is no phpdoc for getReflectionClass method
https://github.com/doctrine/mongodb-odm/blob/e3352c0783886e525d2b8accb8bc7984148017bf/lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php#L894

Might be better to consider removing the getReflectionClass stub in order to have the same situation that the original library
or to update the original libraries first ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Reviewers
No reviews
Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /