Skip to content

Fix phpstan/phpstan#11351: Defining Array Constants in PHP Traits Causes Errors When Using Class Constants as Keys or Values#5115

Merged
staabm merged 4 commits intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-z3opnu8
Mar 1, 2026
Merged

Fix phpstan/phpstan#11351: Defining Array Constants in PHP Traits Causes Errors When Using Class Constants as Keys or Values#5115
staabm merged 4 commits intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-z3opnu8

Conversation

@phpstan-bot
Copy link
Collaborator

@phpstan-bot phpstan-bot commented Mar 1, 2026

Summary

When a trait defines an array constant that uses self:: to reference class constants (as keys or values), PHPStan falsely reported that the class overrides the trait constant with a different value. This happened because the trait constant expression was resolved in the trait's own context, where self:: couldn't see the using class's constants.

Changes

  • Modified src/Rules/Traits/ConflictingTraitConstantsRule.php to resolve the trait constant value expression using InitializerExprContext::fromClassReflection($classReflection) (the using class) instead of InitializerExprContext::fromClass() with the trait's own name
  • Added regression test in tests/PHPStan/Rules/Traits/data/bug-11351.php with three scenarios: self:: used as array key, as array value, and as both key and value
  • Added test method testBug11351() in tests/PHPStan/Rules/Traits/ConflictingTraitConstantsRuleTest.php

Root cause

In ConflictingTraitConstantsRule, the trait constant's value expression was resolved using InitializerExprContext::fromClass() with the trait's declaring class name. This meant that self::CA in the trait was resolved against the trait itself, which doesn't define CA. The class constant's value, however, was correctly resolved against the using class. This caused a type mismatch (e.g., non-empty-array<int|string, 'CA'> vs array{abc: 'CA'}), triggering a false positive.

The fix resolves both the class and trait constant values in the context of the using class, which matches PHP's runtime behavior where self:: in a trait refers to the class using the trait.

Test

Added tests/PHPStan/Rules/Traits/data/bug-11351.php with three test cases:

  1. Trait constant with self:: as array key
  2. Trait constant with self:: as array value
  3. Trait constant with self:: as both key and value

All expect no errors (the false positives should be gone).

Fixes phpstan/phpstan#11351
Closes phpstan/phpstan#11088

@VincentLanglet VincentLanglet requested a review from staabm March 1, 2026 15:30
@staabm
Copy link
Contributor

staabm commented Mar 1, 2026

will also fix phpstan/phpstan#11088

@staabm
Copy link
Contributor

staabm commented Mar 1, 2026

@phpstan-bot add a regression test for phpstan/phpstan#11088

- Fixed ConflictingTraitConstantsRule to resolve trait constant value expressions
  in the context of the using class, not the trait itself
- When a trait constant uses self::CONST, it should resolve against the using class
  since that's how PHP evaluates trait constants at runtime
- New regression test in tests/PHPStan/Rules/Traits/data/bug-11351.php
@staabm staabm force-pushed the create-pull-request/patch-z3opnu8 branch from f76b0be to f6f4768 Compare March 1, 2026 16:47
@staabm staabm merged commit 9e0d021 into phpstan:2.1.x Mar 1, 2026
408 of 419 checks passed
@VincentLanglet VincentLanglet deleted the create-pull-request/patch-z3opnu8 branch March 8, 2026 12:16
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.

3 participants