Skip to content

Language: DNF parenthesized intersection-only types — parse fails (I1&I2) param/return (Zend/zend_compile.c) #9733

Description

@PurHur

Category

language · php-src-strict · regression vs closed #3094

Problem

PHP 8.2 DNF allows parenthesized intersection-only types such as (I1&I2) $param and function f(): (I1&I2). Unparenthesized I1&I2 $param and union forms like (I1&I2)|null compile here, but parenthesized intersection-only positions fail at parse with unexpected T_VARIABLE, expecting '|'.

php-src reference

Repro (failure today)

<?php
declare(strict_types=1);

interface I1 {}
interface I2 {}
class Both implements I1, I2 {}

function accepts((I1&I2) $o): string { return 'ok'; }
function returns(): (I1&I2) { return new Both(); }

var_export(accepts(new Both()));
var_export(returns() instanceof Both);
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && php bin/vm.php test/repro/issue-dnf-paren-intersection-param.php'
php test/repro/issue-dnf-paren-intersection-param.php
Form Zend This compiler
I1&I2 $o OK OK
`(I1&I2) null $o` OK
(I1&I2) $o OK parse error
function f(): (I1&I2) OK parse error

Scope (PHP-in-PHP)

  • Parser / PHPCfg type reconstruction — accept parenthesized intersection leaf in DNF positions
  • lib/VM.php + lib/JIT/ runtime checks once parse succeeds (reuse existing intersection helpers from Language: DNF types — union of intersections (PHP 8.2) #3094)
  • Repro: test/repro/issue-dnf-paren-intersection-param.php

Done when

  • Parameter, return, and property positions accept (I1&I2) without parse error
  • Runtime type check accepts new Both() and rejects non-implementors
  • Compliance guard; ./script/ci-fast.sh --filter dnf_paren_intersection if added

Related

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 18, 2026
  2. PurHur commented on Jun 18, 2026

    @PurHur
    OwnerAuthor

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

  3. PurHur commented on Jun 18, 2026

    @PurHur
    OwnerAuthor

    Merged via #9749.

    Fix: DnfParenTypeRewriter unwraps parenthesized DNF leaves (I1&I2) / (A|B) for nikic/php-parser 4.x when not followed by |; (I1&I2)|null grouping preserved.

    Verification (green):

    • php bin/vm.php test/repro/issue-dnf-paren-intersection-param.php → 'ok' / true
    • php vendor/bin/phpunit test/unit/DnfParenIntersectionTypeTest.php → OK (7 tests)
    • php vendor/bin/phpunit --filter dnf_paren_intersection → OK (2 tests)
    • php script/check-selfhost-spine-coverage-sync.php → OK
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