Skip to content

Stdlib: Zend builtin interfaces — interface_exists()/get_declared_interfaces() must include UnitEnum, BackedEnum, ArrayAccess, Serializable (zend_interfaces.c) #6354

Description

@PurHur

Category

stdlib · language

Problem

Zend registers internal interfaces (UnitEnum, BackedEnum, ArrayAccess, Serializable, …) in the class table. interface_exists() and get_declared_interfaces() must return them even though user code never declared them.

This compiler only scans user-declared interfaces in VmReflection::interfaceExists() / declaredInterfacesTable() (ext/standard/VmReflection.php). Builtin interfaces are missing:

Check Zend PHP 8.2+ bin/vm.php today
interface_exists('UnitEnum') true false
interface_exists('BackedEnum') true false
interface_exists('ArrayAccess') true false
interface_exists('Serializable') true false
in_array('UnitEnum', get_declared_interfaces(), true) true false
is_a($enumCase, UnitEnum::class) true fatal: Unknown class for constant fetch: UnitEnum

instanceof on enum cases for builtin interfaces was fixed in #5711 (closed), but reflection builtins and UnitEnum::class constant fetch still fail — blocking generic enum utilities and self-host code that introspects enums.

php-src reference

Repro

Save as test/repro/parity_builtin_interface_registry.php:

<?php
enum E: string { case A = 'a'; }
$c = E::A;

foreach (['UnitEnum', 'BackedEnum', 'ArrayAccess', 'Serializable'] as $iface) {
    echo "interface_exists($iface): ", var_export(interface_exists($iface), true), "\n";
}
echo "declared UnitEnum: ", var_export(in_array('UnitEnum', get_declared_interfaces(), true), true), "\n";
echo "is_a case UnitEnum: ";
try {
    var_export(is_a($c, UnitEnum::class));
} catch (Throwable $e) {
    echo get_class($e), ': ', $e->getMessage();
}
echo "\n";
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
php test/repro/parity_builtin_interface_registry.php
php bin/vm.php test/repro/parity_builtin_interface_registry.php 2>&1 | grep -v listSpreadRhs
'

Scope (this repo)

Area Path
Registry lib/VM/BuiltinInterfaces.php (new) — seed internal ClassEntry rows at VM init
Enum parity lib/VM/EnumSupport.php — ensure enum cases satisfy instanceof builtin interfaces (regression guard for #5711)
Stdlib ext/standard/VmReflection.php — interfaceExists(), declaredInterfacesTable() include builtins
Constant fetch lib/VM.php / class table — resolve UnitEnum::class, BackedEnum::class for is_a() / is_subclass_of()
JIT ext/standard/JitInterfaceExists.php, lib/JIT/ReflectionBuiltinHelper.php — literal builtin interface names
Tests test/compliance/cases/stdlib/builtin_interface_exists.phpt, test/compliance/cases/language/enum_is_a_unit_enum.phpt

PHP-in-PHP: register builtins in PHP (lib/VM/), not new C tables in runtime/.

Done when

Verification

./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && vendor/bin/phpunit --filter builtin_interface'

Links

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:vmVirtual machineenhancementNew feature or requestimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimphase-2:languagePhase 2 – language featuresphase-4:stdlibPhase 4 – stdlib for web apps

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions