Skip to content

Fix inconsistent type inference#4928

Open
xHeaven wants to merge 4 commits intophpstan:2.1.xfrom
xHeaven:inference
Open

Fix inconsistent type inference#4928
xHeaven wants to merge 4 commits intophpstan:2.1.xfrom
xHeaven:inference

Conversation

@xHeaven
Copy link
Contributor

@xHeaven xHeaven commented Feb 14, 2026


$this->processStmtNodesInternal($stmt, $classLikeStatements, $classScope, $storage, $classStatementsGatherer, $context);
foreach ($stmt->stmts as $classLikeStmt) {
if (!$classLikeStmt instanceof Node\Stmt\ClassConst || !$classLikeStmt->isPublic()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please also add a test when the constant is private:

https://3v4l.org/qhTGS#veol

I wonder why this works before the PR already

https://phpstan.org/r/5e8b0fd5-fa52-4787-bcd5-cb25eed12508

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm gonna add a few more tests with fixes. Also, I think I've accidentally fixed this:

assertType('*ERROR*', self::COALESCE_SPECIAL); // could be 42

I'm not sure if this was supposed to be fixed? It would make sense, though. Now it correctly resolves to 42 and the *ERROR* assertion fails.

I wonder why this works before the PR already
phpstan.org/r/5e8b0fd5-fa52-4787-bcd5-cb25eed12508

It doesn't look like working to me. It prints Dumped type: Closure(int): array, it should print Dumped type: Closure(int): array{num: int}.

}

foreach ($classLikeStmt->consts as $const) {
$scope = $scope->assignExpression(
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder why we don't know the full closure type, whereever it is assigned/calculated before this PR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We already inferred it, but scope transitions dropped ClassConstFetch/self::CONST info, so lookup fell back to reflection and lost shape precision.

@xHeaven
Copy link
Contributor Author

xHeaven commented Feb 14, 2026

Pushed some more tests and changes.


Oh well, it seems this broke some things in the legacy resolver...

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.

2 participants