diff --git a/lib/VM/EnumCaseSupport.php b/lib/VM/EnumCaseSupport.php index 32dd5f344f1..5227b19d96f 100644 --- a/lib/VM/EnumCaseSupport.php +++ b/lib/VM/EnumCaseSupport.php @@ -306,9 +306,10 @@ public static function compareEnumCaseEntrySpaceship(EnumCaseEntry $left, EnumCa } /** - * Transitive ordering for sort()/asort() on enum case arrays (#5546, php-src array.c php_array_compare_transitive). + * Transitive ordering for sort()/asort() on enum case arrays (#5546, #5691, php-src array.c). * - * Backed enums: backing scalar spaceship. Unit enums: object handle (spl_object_id order). + * php-src SORT_REGULAR uses stable object-handle order for enum zvals, not backing scalars + * (php_array_data_compare_unstable_i / php_array_compare_transitive, PR #20517). */ public static function compareEnumCasesForSort(Variable $left, Variable $right): int { @@ -323,12 +324,6 @@ public static function compareEnumCasesForSort(Variable $left, Variable $right): if ($leftName === $rightName) { return 0; } - if (null !== $leftClass->backedType) { - return Variable::spaceshipCompare( - self::backingValueForMinMax($left), - self::backingValueForMinMax($right) - ); - } return self::objectIdForEnumSort($left) <=> self::objectIdForEnumSort($right); } diff --git a/test/compliance/cases/stdlib/sort_enum_cases.phpt b/test/compliance/cases/stdlib/sort_enum_cases.phpt index c068efa098f..51fee157148 100644 --- a/test/compliance/cases/stdlib/sort_enum_cases.phpt +++ b/test/compliance/cases/stdlib/sort_enum_cases.phpt @@ -1,9 +1,11 @@ --TEST-- -stdlib sort() on enum case arrays preserves objects (#5546, ext/standard/array.c) +stdlib sort() on enum case arrays preserves objects (#5546, #5691, ext/standard/array.c) --FILE-- name, ($v instanceof EUnit ? '' : '!'), "\n"; } + +$c = [EStr::B, EStr::A]; +sort($c); +foreach ($c as $v) { + echo $v->name, ($v instanceof EStr ? '' : '!'), "\n"; +} + +$d = [EOrder::B, EOrder::C, EOrder::A]; +sort($d); +foreach ($d as $v) { + echo $v->name, ($v instanceof EOrder ? '' : '!'), "\n"; +} --EXPECT-- A B C A B +A +B +A +B +C diff --git a/test/unit/SortEnumCasesBuiltinTest.php b/test/unit/SortEnumCasesBuiltinTest.php index 0df046d0a7e..6bd144db144 100644 --- a/test/unit/SortEnumCasesBuiltinTest.php +++ b/test/unit/SortEnumCasesBuiltinTest.php @@ -79,4 +79,38 @@ enum EInt: int { case A = 1; case B = 2; } $this->assertSame('B,A', $output); } + + /** @covers issue #5691 */ + public function testStringBackedEnumSortUsesObjectHandleOrder(): void + { + ob_start(); + $runtime = new Runtime(); + $runtime->run($runtime->parseAndCompile(<<<'PHP' +name, ',', $a[1]->name; +PHP, 'sort_string_backed_enum.php')); + $output = ob_get_clean(); + + $this->assertSame('A,B', $output); + } + + /** @covers issue #5691 */ + public function testIntBackedEnumSortUsesDeclarationHandleNotBackingValue(): void + { + ob_start(); + $runtime = new Runtime(); + $runtime->run($runtime->parseAndCompile(<<<'PHP' + $v->name, $a)); +PHP, 'sort_enum_declaration_order.php')); + $output = ob_get_clean(); + + $this->assertSame('C,A,B', $output); + } }