Skip to content

Language: list destructuring with spread — [$a, ...$rest] = $arr (zend_compile.c) #4835

Description

@PurHur

Category

language

Problem

PHP supports array destructuring with spread: [$head, ...$tail] = $array (and keyed variants). Zend compiles this in zend_compile.c by assigning sequential elements then merging the remainder.

This compiler’s php-cfg fork (vendor/ircmaxell/php-cfg/lib/PHPCfg/Parser.php::parseListAssignment) walks list items but ignores $item->unpack, so spread arms are treated like ordinary numeric slots — wrong variables receive values or compile fails.

Array-literal spread ([...$a]) works via TYPE_ARRAY_SPREAD; list-assign spread is a separate lowering path.

php-src reference

Repro (failure today)

<?php
$src = [1, 2, 3, 4];
[$a, ...$rest] = $src;
echo $a, ':', implode(',', $rest), "\n";
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
php repro.php
php bin/vm.php repro.php 2>&1
'
Runtime Expected Typical today
Zend PHP 8.x 1:2,3,4 —
bin/vm.php same wrong values, compile error, or spread arm ignored

Keyed spread (stretch goal in same issue or follow-up):

['x' => $x, ...$others] = ['x' => 1, 'y' => 2];

Scope (this repo)

Module Path
php-cfg patches/php-cfg-list-spread.patch (new) — teach parseListAssignment unpack arms
Compiler lib/Compiler.php — opcodes after TYPE_LIST_UNPACK_CHECK for spread tail
VM / JIT lib/VM.php, lib/JIT/ListUnpackHelper.php — append remaining list elements into $rest array
Tests test/compliance/cases/language/list_destructuring_spread.phpt

Done when

  • Packed-list repro prints 1:2,3,4 on VM matching Zend
  • By-ref spread [$a, &$b, ...$c] matches Zend when supported by php-parser
  • JIT/AOT: same semantics or documented VM-only v1 with matrix note
  • ./script/ci-fast.sh --filter list_destructuring_spread green

Related

Links

Activity

  1. added
    enhancementNew feature or request
    area:vmVirtual machine
    implementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claim
    on Jun 3, 2026
  2. PurHur commented on Jun 3, 2026

    @PurHur
    OwnerAuthor

    claim: cursor-agent-lane-c — starting this run

  3. PurHur commented on Jun 3, 2026

    @PurHur
    OwnerAuthor

    Merged via #4843.

    Verification

    • php bin/vm.php test/repro/list_destructuring_spread_4835.php → 1:2,3,4
    • vendor/bin/phpunit --filter list_destructuring_spread → OK (1 test)

    JIT/AOT execute for list spread remains VM-only (JITTest skip); follow-up can mirror HashTable::sliceCopy in MCJIT.

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:compilerCompiler / CFG / JITarea:vmVirtual machineenhancementNew feature or requestimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimphase-2:languagePhase 2 – language features

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions