-
Notifications
You must be signed in to change notification settings - Fork 557
Fix phpstan/phpstan#14351: Missing errors arround use of $this #5278
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
Merged
ondrejmirtes
merged 4 commits into
phpstan:2.1.x
from
phpstan-bot:create-pull-request/patch-hozp2ll
Mar 24, 2026
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
b9b16be
Fix phpstan/phpstan#14351: Missing errors around use of $this
phpstan-bot e210bca
Add bug-14351.php to make-lint exclude list
phpstan-bot 398df87
Also detect `static $this` as fatal error
phpstan-bot d98b140
Use catch type as assigned expression in VariableAssignNode for catch…
phpstan-bot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| <?php declare(strict_types = 1); | ||
|
|
||
| namespace PHPStan\Rules\Variables; | ||
|
|
||
| use PhpParser\Node; | ||
| use PhpParser\Node\Expr\Variable; | ||
| use PHPStan\Analyser\Scope; | ||
| use PHPStan\DependencyInjection\RegisteredRule; | ||
| use PHPStan\Rules\Rule; | ||
| use PHPStan\Rules\RuleErrorBuilder; | ||
| use function is_string; | ||
|
|
||
| /** | ||
| * @implements Rule<Node\Stmt\Global_> | ||
| */ | ||
| #[RegisteredRule(level: 0)] | ||
| final class ThisInGlobalStatementRule implements Rule | ||
| { | ||
|
|
||
| public function getNodeType(): string | ||
| { | ||
| return Node\Stmt\Global_::class; | ||
| } | ||
|
|
||
| public function processNode(Node $node, Scope $scope): array | ||
| { | ||
| $errors = []; | ||
| foreach ($node->vars as $var) { | ||
| if (!$var instanceof Variable) { | ||
| continue; | ||
| } | ||
| if (!is_string($var->name)) { | ||
| continue; | ||
| } | ||
| if ($var->name !== 'this') { | ||
| continue; | ||
| } | ||
|
|
||
| $errors[] = RuleErrorBuilder::message('Cannot use $this as global variable.') | ||
| ->identifier('global.this') | ||
| ->nonIgnorable() | ||
| ->build(); | ||
| } | ||
|
|
||
| return $errors; | ||
| } | ||
|
|
||
| } |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| <?php declare(strict_types = 1); | ||
|
|
||
| namespace PHPStan\Rules\Variables; | ||
|
|
||
| use PhpParser\Node; | ||
| use PHPStan\Analyser\Scope; | ||
| use PHPStan\DependencyInjection\RegisteredRule; | ||
| use PHPStan\Rules\Rule; | ||
| use PHPStan\Rules\RuleErrorBuilder; | ||
| use function is_string; | ||
|
|
||
| /** | ||
| * @implements Rule<Node\Stmt\Static_> | ||
| */ | ||
| #[RegisteredRule(level: 0)] | ||
| final class ThisInStaticStatementRule implements Rule | ||
| { | ||
|
|
||
| public function getNodeType(): string | ||
| { | ||
| return Node\Stmt\Static_::class; | ||
| } | ||
|
|
||
| public function processNode(Node $node, Scope $scope): array | ||
| { | ||
| $errors = []; | ||
| foreach ($node->vars as $var) { | ||
| if (!is_string($var->var->name)) { | ||
| continue; | ||
| } | ||
| if ($var->var->name !== 'this') { | ||
| continue; | ||
| } | ||
|
|
||
| $errors[] = RuleErrorBuilder::message('Cannot use $this as static variable.') | ||
| ->identifier('static.this') | ||
| ->nonIgnorable() | ||
| ->build(); | ||
| } | ||
|
|
||
| return $errors; | ||
| } | ||
|
|
||
| } |
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
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
29 changes: 29 additions & 0 deletions
29
tests/PHPStan/Rules/Variables/ThisInGlobalStatementRuleTest.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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| <?php declare(strict_types = 1); | ||
|
|
||
| namespace PHPStan\Rules\Variables; | ||
|
|
||
| use PHPStan\Rules\Rule; | ||
| use PHPStan\Testing\RuleTestCase; | ||
|
|
||
| /** | ||
| * @extends RuleTestCase<ThisInGlobalStatementRule> | ||
| */ | ||
| class ThisInGlobalStatementRuleTest extends RuleTestCase | ||
| { | ||
|
|
||
| protected function getRule(): Rule | ||
| { | ||
| return new ThisInGlobalStatementRule(); | ||
| } | ||
|
|
||
| public function testBug14351(): void | ||
| { | ||
| $this->analyse([__DIR__ . '/data/bug-14351.php'], [ | ||
| [ | ||
| 'Cannot use $this as global variable.', | ||
| 15, | ||
| ], | ||
| ]); | ||
| } | ||
|
|
||
| } |
29 changes: 29 additions & 0 deletions
29
tests/PHPStan/Rules/Variables/ThisInStaticStatementRuleTest.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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| <?php declare(strict_types = 1); | ||
|
|
||
| namespace PHPStan\Rules\Variables; | ||
|
|
||
| use PHPStan\Rules\Rule; | ||
| use PHPStan\Testing\RuleTestCase; | ||
|
|
||
| /** | ||
| * @extends RuleTestCase<ThisInStaticStatementRule> | ||
| */ | ||
| class ThisInStaticStatementRuleTest extends RuleTestCase | ||
| { | ||
|
|
||
| protected function getRule(): Rule | ||
| { | ||
| return new ThisInStaticStatementRule(); | ||
| } | ||
|
|
||
| public function testBug14351(): void | ||
| { | ||
| $this->analyse([__DIR__ . '/data/bug-14351.php'], [ | ||
| [ | ||
| 'Cannot use $this as static variable.', | ||
| 19, | ||
| ], | ||
| ]); | ||
| } | ||
|
|
||
| } |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| <?php declare(strict_types = 1); | ||
|
|
||
| namespace Bug14351; | ||
|
|
||
| class C { | ||
| function foo(): void { | ||
| try { | ||
| throw new \Exception(); | ||
| } catch (\Exception $this) { // should report: Cannot re-assign $this | ||
| } | ||
| } | ||
| } | ||
|
|
||
| function foo(): void { | ||
| global $this; // should report: Cannot use $this as global variable | ||
| } | ||
|
|
||
| function bar(): void { | ||
| static $this; // should report: Cannot use $this as static variable | ||
| } | ||
22 changes: 22 additions & 0 deletions
22
tests/PHPStan/Rules/Variables/data/parameter-out-catch-variable.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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| <?php | ||
|
|
||
| namespace ParameterOutCatchVariable; | ||
|
|
||
| /** | ||
| * @param-out int $p | ||
| */ | ||
| function foo(&$p): void { | ||
| try { | ||
| throw new \Exception(); | ||
| } catch (\Exception $p) { | ||
|
|
||
| } | ||
| } | ||
|
|
||
| function bar(int &$p): void { | ||
| try { | ||
| throw new \Exception(); | ||
| } catch (\Exception $p) { | ||
|
|
||
| } | ||
| } |
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
another case we miss atm is
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This task also already completed successfully — all 11647 tests passed. Everything has been committed and pushed.