Skip to content

Fix incorrect type inference for @phpstan-assert-if-true on $this with union types #4246

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
wants to merge 5 commits into
base: 2.1.x
Choose a base branch
from

Conversation

yt-catpaw
Copy link

@yt-catpaw yt-catpaw commented Aug 17, 2025

closes phpstan/phpstan#13358
closes phpstan/phpstan#11441

Summary

@phpstan-assert-if-true on $this with union types produced incorrect type inference.

Repro

See added test: tests/PHPStan/Rules/Methods/AssertIfTrueOnThisTest.php.

Cause

Union handling for $this assertions wasn’t propagated into TypeSpecifier (assert-based refinement path).

Fix

Normalize/refine $this union members before producing SpecifiedTypes from assert info.

Tests

  • Added/updated tests in AssertIfTrueOnThisTest.php.
  • Full test suite passes locally.

Also fixes #11441

  • Added regression test in tests/PHPStan/Analyser/nsrt/bug-11441.php.
  • This ensures that @phpstan-assert !null $this->getParam() works correctly when called on union types (Foo|Bar), where each class defines its own method.
  • Previously, the null type was not removed in such cases. After the fix, int|string is correctly inferred.

@staabm
Copy link
Contributor

staabm commented Aug 18, 2025

please have a look at the issue-bot github action job summary. it seems this PR also affects other issues.

please add regression tests for those which are getting fixed

@yt-catpaw
Copy link
Author

Thanks, @staabm. I’ll review the issue-bot GitHub Action job summary and add regression tests for the additionally affected issues. This is my first time contributing to open source (and my first PR to PHPStan), so I’ll update this PR in small batches as I add tests. If you prefer a specific location or pattern for these tests, please let me know.

@staabm
Copy link
Contributor

staabm commented Aug 18, 2025

Welcome 🤗

Type related tests go usually into the https://github.com/phpstan/phpstan-src/tree/2.1.x/tests/PHPStan/Analyser/nsrt/ directory.

Files located in this directory will automatically checked against using assertType().

@ondrejmirtes
Copy link
Member

Regression tests are typically added to existing test classes for rules that reported the (disappeared) errors.

Alternatively covering some bugs with simple type inference tests (in tests/PHPStan/Analyser/nsrt) is good enough.

@@ -0,0 +1,40 @@
<?php declare(strict_types=1);

namespace Bug13358;
Copy link
Contributor

Choose a reason for hiding this comment

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

You can move this also into nsrt/ folder

Copy link
Author

@yt-catpaw yt-catpaw Aug 19, 2025

Choose a reason for hiding this comment

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

Done.
31b55ac


use PHPStan\Testing\TypeInferenceTestCase;

class AssertIfTrueOnThisTest extends TypeInferenceTestCase
Copy link
Contributor

Choose a reason for hiding this comment

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

This file can be dropped when everything else moved into nsrt/

Copy link
Author

@yt-catpaw yt-catpaw Aug 19, 2025

Choose a reason for hiding this comment

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

Done.
31b55ac

@yt-catpaw yt-catpaw marked this pull request as draft August 19, 2025 04:02
@yt-catpaw
Copy link
Author

@staabm
Hi, I’ve moved the test case for bug-13358 into tests/PHPStan/Analyser/nsrt/bug-13358.php, but now I’m not sure how to run just this specific test file.

The reason I want to run it individually is because I’d like to debug a specific function and check only the information related to this test case, without running everything else.

Could you tell me how to do that?

Thanks!

@yt-catpaw yt-catpaw marked this pull request as ready for review August 21, 2025 15:56
@phpstan-bot
Copy link
Collaborator

This pull request has been marked as ready for review.

@yt-catpaw yt-catpaw requested a review from staabm August 21, 2025 16:25
@yt-catpaw
Copy link
Author

Added regression test for #11441 (bug-11441.php) and updated the description accordingly.
Let me know if anything else is needed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Narrowing type using @phpstan-assert-if-true doesn't work with $this on abstract class @phpstan-assert isn't working with Union
5 participants