[php-src] PR #25330: zend_ast: Fix AST export of static member names that do not lex as identifiers
| From: | jorgsowa | Date: | Sun, 08 Nov 2026 20:48:00 +0000 |
| Subject: | [php-src] PR #25330: zend_ast: Fix AST export of static member names that do not lex as identifiers | ||
| Groups: | php.git-pulls | ||
| Request: | Send a blank email to git-pulls+get-40448@lists.php.net to get a copy of this message | ||
Pull Request: https://github.com/php/php-src/pull/25330
Author: jorgsowa
The AST export of static method calls and class constant fetches prints dynamic member names without
braces, even when the bare name doesn't lex as an identifier. The exported code then fails to
parse:
```php
assert(false && C::{'__halt_compiler'}());
// AssertionError: assert(false && C::__halt_compiler())
// re-parsing it: syntax error, unexpected token "__halt_compiler"
```
Three cases are affected:
-
__halt_compiler: T_HALT_COMPILER is the only keyword the grammar does not accept as
an identifier, so C::{'__halt_compiler'} cannot be written as
C::__halt_compiler.
- Names that aren't valid labels: static call names went through the variable-name export path,
so C::{'a b'}() became C::{a b}() and
C::{''}() became C::{}().
- public/protected/private calls: C::public( set ) was exported as
C::public(set), which the lexer reads as the single T_PUBLIC_SET token.
These names are now exported in braces: C::{'__halt_compiler'}(), C::{'a b'}(),
C::{'public'}(set). A static call named public, protected or private is always braced,
because only its arguments decide whether it would lex as T_*_SET, and the braced form is always
valid.
Follow-up to #25221.