Skip to content

Possibly unnecessary binding of variables across arrow functions? #19867

@MorganLOCode

Description

@MorganLOCode

Description

The following code:

<?php
foo(fn($a) => array_map(fn($b) => $a + $b, $array));

Resulted in this (level 2) opcode output:

$_main:
     ; (lines=7, args=0, vars=2, tmps=1)
     ; (after optimizer)
     ; C:\tmp\test\test.php:1-6
0000 INIT_FCALL 1 96 string("foo")
0001 T2 = DECLARE_LAMBDA_FUNCTION 0
0002 BIND_LEXICAL T2 CV0($b)
0003 BIND_LEXICAL T2 CV1($array)
0004 SEND_VAL T2 1
0005 DO_UCALL
0006 RETURN int(1)
LIVE RANGES:
     2: 0002 - 0004 (tmp/var)

{closure:C:\tmp\test\test.php:5}:
     ; (lines=10, args=1, vars=3, tmps=1)
     ; (after optimizer)
     ; C:\tmp\test\test.php:5-5
0000 CV0($a) = RECV 1
0001 BIND_STATIC CV1($b)
0002 BIND_STATIC CV2($array)
0003 INIT_FCALL 2 112 string("array_map")
0004 T3 = DECLARE_LAMBDA_FUNCTION 0
0005 BIND_LEXICAL T3 CV0($a)
0006 SEND_VAL T3 1
0007 SEND_VAR CV2($array) 2
0008 V3 = DO_ICALL
0009 RETURN V3
LIVE RANGES:
     3: 0005 - 0006 (tmp/var)

{closure:{closure:C:\tmp\test\test.php:5}:5}:
     ; (lines=4, args=1, vars=2, tmps=1)
     ; (after optimizer)
     ; C:\tmp\test\test.php:5-5
0000 CV0($b) = RECV 1
0001 BIND_STATIC CV1($a)
0002 T2 = ADD CV1($a) CV0($b)
0003 RETURN T2

Notice line 0002 of $_main and line 0001 of the outer closure: $b is being bound even though its only appearance and use is local to the inner closure. (While $b does explicitly appear inside the outer arrow function and this would be why it's being captured, the fact that it does so as a parameter of the inner arrow function is being ignored).
I'm not sure if this could cause problems, but it seems unnecessary.

PHP Version

PHP 8.4.12 (cli) (built: Aug 26 2025 21:18:21) (ZTS Visual C++ 2022 x64)
Copyright (c) The PHP Group
Zend Engine v4.4.12, Copyright (c) Zend Technologies
    with Zend OPcache v8.4.12, Copyright (c), by Zend Technologies

Operating System

Windows 10

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions