diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/AtomicPropertyFetchAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/AtomicPropertyFetchAnalyzer.php index 0fdc76b40ce..f01f379e26a 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/AtomicPropertyFetchAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/AtomicPropertyFetchAnalyzer.php @@ -1141,6 +1141,8 @@ private static function handleNonExistentClass( $override_property_visibility = $interface_storage->override_property_visibility; + $intersects_with_enum = false; + foreach ($intersection_types as $intersection_type) { if ($intersection_type instanceof TNamedObject && $codebase->classExists($intersection_type->value) @@ -1149,12 +1151,19 @@ private static function handleNonExistentClass( $class_exists = true; return; } + if ($intersection_type instanceof TNamedObject + && (in_array($intersection_type->value, ['UnitEnum', 'BackedEnum'], true) + || in_array('UnitEnum', $codebase->getParentInterfaces($intersection_type->value))) + ) { + $intersects_with_enum = true; + } } if (!$class_exists && //interfaces can't have properties. Except when they do... In PHP Core, they can !in_array($fq_class_name, ['UnitEnum', 'BackedEnum'], true) && - !in_array('UnitEnum', $codebase->getParentInterfaces($fq_class_name)) + !in_array('UnitEnum', $codebase->getParentInterfaces($fq_class_name)) && + !$intersects_with_enum ) { if (IssueBuffer::accepts( new NoInterfaceProperties( diff --git a/tests/EnumTest.php b/tests/EnumTest.php index 12322c66698..0cb1c2c0e4d 100644 --- a/tests/EnumTest.php +++ b/tests/EnumTest.php @@ -630,6 +630,33 @@ enum BarEnum: int { 'ignored_issues' => [], 'php_version' => '8.1', ], + 'allowPropertiesOnIntersectionsWithEnumInterfaces' => [ + 'code' => <<<'PHP' + name; + } + if ($i instanceof UnitEnum) { + echo $i->name; + } + if ($i instanceof UE) { + echo $i->name; + } + if ($i instanceof BE) { + echo $i->name; + } + } + PHP, + 'assertions' => [], + 'ignored_issues' => [], + 'php_version' => '8.1', + ], ]; }