Skip to content

Check the #[\Override] attribute on class constants and enum cases - #6685

Open
Amoifr wants to merge 5 commits into
phpstan:2.3.xfrom
Amoifr:feature-15370-override-constants
Open

Amoifr wants to merge 5 commits into
phpstan:2.3.xfrom
Amoifr:feature-15370-override-constants

Conversation

@Amoifr

@Amoifr Amoifr commented Oct 5, 2026

Copy link
Copy Markdown

Closes phpstan/phpstan#15370

PHP 8.6 allows #[\Override] on class constants and enum cases (RFC). This follows what was done for properties in 8b85e62, 7f73847 and 64e9776:

  • A constant or enum case with #[\Override] that overrides nothing is reported (classConstant.override, enum.caseOverride), regardless of the PHP version, like methods and properties. A private parent constant does not count, as the RFC says. The fix removes the attribute.
  • A constant or enum case that overrides an inherited one without #[\Override] is reported (classConstant.missingOverride, enum.caseMissingOverride) when the new checkMissingOverrideConstantAttribute parameter is enabled. When it is null (the default), it follows checkMissingOverrideMethodAttribute on PHP 8.6+, like checkMissingOverridePropertyAttribute does on PHP 8.5+. The fix adds the attribute. Constants declared in traits are skipped, as for properties.

The shared logic lives in OverrideAttributeOnConstantCheck, used by OverridingConstantRule and a new OverridingEnumCaseRule (enum cases are EnumCase nodes, and their prototype can only come from an interface). For const A = 1, B = 2; the attribute applies to both constants, so no fix is offered there.

The new parameter mirrors the property one. If you would rather reuse checkMissingOverrideMethodAttribute without a dedicated parameter, I'm happy to change it. I have not touched the documentation on the website.

trait FooTrait
{
#[\Override]
const FROM_PARENT = 5;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Parse error: tests/PHPStan/Rules/Constants/data/constant-override-attr.php:57
    55| {
    56| 	#[\Override]
  > 57| 	const FROM_PARENT = 5;
    58| 
    59| 	const PROTECTED_FROM_PARENT = 5;
Traits cannot have constants

I think you need // lint >= 8.2 rather than // lint >= 8.0.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good catch, thanks! Trait constants need 8.2, so the fixture is now // lint >= 8.2 and both tests require PHP 8.2. I also added a test with a 8.5 to 8.6 version range for the missing attribute check.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Lint build is still failing ; check at

------------------------------------------------------------
Parse error: tests/PHPStan/Rules/Constants/data/constant-override-attr-fix.php:15
    13| 
    14| 	#[\Override]
  > 15| 	const BAR = 2;
    16| }
Attribute "Override" cannot target class constant (allowed targets: method, property)
------------------------------------------------------------
Parse error: tests/PHPStan/Rules/Constants/data/constant-override-attr.php:20
    18| {
    19| 	#[\Override]
  > 20| 	const FROM_INTERFACE = 2;
    21| 
    22| 	#[\Override]
Attribute "Override" cannot target class constant (allowed targets: method, property)
------------------------------------------------------------
Parse error: tests/PHPStan/Rules/EnumCases/data/enum-case-override-attr.php:13
    11| {
    12| 	#[\Override]
  > 13| 	case FOO = 'foo';
    14| 
    15| 	#[\Override]
Attribute "Override" cannot target class constant (allowed targets: method, property)

https://github.com/phpstan/phpstan-src/actions/runs/37407089096/job/112086933426?pr=6685

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks, and sorry for the second round! #[\Override] on a class constant only compiles on PHP 8.6, so the three fixtures are now // lint >= 8.6. I also checked them with php -l this time.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

One more: PHP 8.6 itself rejects an #[\Override] that overrides nothing, so the two constant fixtures are now excluded from lint, like property-override-attr.php. I checked the whole lint target with the official php:8.6-rc-cli image this time. Sorry for the noise!

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.

#[\Override] can be applied to class constants, including enum cases in PHP 8.6

2 participants