Skip to content

Commit 5bedf6f

Browse files
committed
docs: add generics in NEWS, UPGRADING, and UPGRADING.INTERNALS
Signed-off-by: azjezz <azjezz@protonmail.com>
1 parent 332e214 commit 5bedf6f

3 files changed

Lines changed: 99 additions & 0 deletions

File tree

NEWS

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ PHP NEWS
33
?? ??? ????, PHP 8.6.0alpha1
44

55
- Core:
6+
. Added generics: type parameters on classes, interfaces, traits, functions,
7+
methods, closures, and arrow functions, with optional bounds, defaults,
8+
and variance markers; turbofish syntax (`f::<int>()`) at call sites; and
9+
type arguments on named types (`Box<int>`, `array<K, V>`, `iterable<T>`,
10+
`self<T>`, `static<T>`, `parent<T>`). Type parameters erase to their bound
11+
at runtime; type arguments are discarded. Pre-erasure metadata is preserved
12+
for Reflection so static-analysis tools can consume generics without
13+
re-parsing source. (azjezz)
614
. Added first-class callable cache to share instances for the duration of the
715
request. (ilutov)
816
. It is now possible to use reference assign on WeakMap without the key

UPGRADING

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,31 @@ PHP 8.6 UPGRADE NOTES
127127
========================================
128128

129129
- Core:
130+
. Added support for runtime-bound-checked generics. Classes, interfaces,
131+
traits, functions, methods, closures, and arrow functions can now declare
132+
type parameters with optional bounds (`T : Foo`), defaults (`T = int`),
133+
and variance markers (`+T`, `-T`):
134+
135+
class Box<T : object> {
136+
public T $value;
137+
public function get(): T { return $this->value; }
138+
}
139+
140+
function id<T>(T $x): T { return $x; }
141+
142+
Call sites accept turbofish type arguments (`Box::<int>::new()`,
143+
`id::<int>(7)`); use sites accept type arguments on named types
144+
(`Box<int>`, `array<int, string>`, `iterable<T>`, `self<T>`,
145+
`static<T>`, `parent<T>`). Recursive bounds (`T : Comparable<T>`)
146+
are supported. Anonymous classes cannot declare type parameters.
147+
148+
At runtime each type parameter is replaced by its declared bound
149+
(or `mixed` when unbounded, or when the bound is invalid in the
150+
target position, e.g. `callable` on a property), and type
151+
arguments are discarded. Pre-erasure metadata is preserved on
152+
functions, methods, and class entries and is exposed through
153+
Reflection so that PHP-based static-analysis tools can consume
154+
generics without re-parsing source.
130155
. It is now possible to use reference assign on WeakMap without the key
131156
needing to be present beforehand.
132157

@@ -232,6 +257,15 @@ PHP 8.6 UPGRADE NOTES
232257
RFC: https://wiki.php.net/rfc/isreadable-iswriteable
233258
. Added ReflectionParameter::getDocComment().
234259
RFC: https://wiki.php.net/rfc/parameter-doccomments
260+
. Added ReflectionFunctionAbstract::isGeneric() and
261+
ReflectionFunctionAbstract::getGenericParameters() (covers
262+
ReflectionFunction, ReflectionMethod, closures, and arrow functions).
263+
. Added ReflectionClass::isGeneric() and
264+
ReflectionClass::getGenericParameters().
265+
. Added ReflectionNamedType::hasGenericArguments() and
266+
ReflectionNamedType::getGenericArguments(). The arguments are returned
267+
as ReflectionType instances in source order (pre-erasure form);
268+
ReflectionNamedType::getName() continues to return the erased name.
235269

236270
- Intl:
237271
. `grapheme_strrev()` returns strrev for grapheme cluster unit.
@@ -258,6 +292,15 @@ PHP 8.6 UPGRADE NOTES
258292
. Openssl\Session
259293
RFC: https://wiki.php.net/rfc/tls_session_resumption
260294

295+
- Reflection:
296+
. ReflectionGenericTypeParameter (final, instances obtained via
297+
ReflectionClass::getGenericParameters() and
298+
ReflectionFunctionAbstract::getGenericParameters()).
299+
. ReflectionTypeParameterReference (extends ReflectionType, appears only
300+
inside pre-erasure type expressions: bounds, defaults, and the elements
301+
of ReflectionNamedType::getGenericArguments()).
302+
. enum ReflectionGenericVariance { Invariant; Covariant; Contravariant }.
303+
261304
- Standard:
262305
. enum SortDirection
263306
RFC: https://wiki.php.net/rfc/sort_direction_enum

UPGRADING.INTERNALS

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,54 @@ PHP 8.6 INTERNALS UPGRADE NOTES
103103
. The deprecated Z_IMMUTABLE(), Z_IMMUTABLE_P(), Z_OPT_IMMUTABLE(), and
104104
Z_OPT_IMMUTABLE_P() macros have been removed. Check for
105105
IS_ARRAY && !REFCOUNTED directly.
106+
. Added support for runtime-bound-checked generic type parameters. The
107+
main additions:
108+
. New types in zend_compile.h: zend_generic_parameter,
109+
zend_generic_parameter_list, zend_generic_type_table, and
110+
zend_generic_scope_entry. Allocate / destroy via
111+
zend_generic_parameter_list_alloc(),
112+
zend_generic_parameter_list_destroy(),
113+
zend_generic_type_table_alloc(), and
114+
zend_generic_type_table_destroy().
115+
. zend_op_array and zend_class_entry both gained an optional
116+
`generic_parameters` (declared parameter list) and an optional
117+
`generic_types` side table holding the pre-erasure forms of
118+
return types, parameter types, property types, class-constant
119+
types, the extends type, implements list, and trait-use list.
120+
The runtime arg_info / property / class-constant slots continue
121+
to hold only the erased form.
122+
. New AST kinds: ZEND_AST_GENERIC_TYPE_PARAMETER_LIST,
123+
ZEND_AST_GENERIC_TYPE_PARAMETER, ZEND_AST_GENERIC_NAMED_TYPE,
124+
ZEND_AST_GENERIC_TYPE_ARGUMENT_LIST, ZEND_AST_TURBOFISH.
125+
. zend_ast_decl::child[] grew from 5 to 6 entries; the new slot
126+
carries an optional generic-parameter-list AST.
127+
. The child-count groups of ZEND_AST_CALL, ZEND_AST_NEW,
128+
ZEND_AST_METHOD_CALL, ZEND_AST_NULLSAFE_METHOD_CALL, and
129+
ZEND_AST_STATIC_CALL each gained one optional child holding the
130+
call-site turbofish type-argument list. Code that walks these
131+
nodes by hard-coded child count must be updated.
132+
. zend_ast_export handles the new generic AST kinds.
133+
. Two new bits on zend_type's type_mask:
134+
_ZEND_TYPE_TYPE_PARAMETER_BIT (1u << 25) and
135+
_ZEND_TYPE_NAMED_WITH_ARGS_BIT (1u << 31), with payload structs
136+
zend_type_parameter_ref { zend_string *name; uint32_t index;
137+
uint8_t origin; } and zend_type_named_with_args { zend_string
138+
*name; uint32_t name_attr; uint32_t count; zend_type args[]; }.
139+
These bits only ever appear in pre-erasure forms held by the
140+
side table; runtime arg_info / property / class-constant types
141+
never carry them. Helpers: ZEND_TYPE_HAS_TYPE_PARAMETER(),
142+
ZEND_TYPE_TYPE_PARAMETER(), ZEND_TYPE_HAS_NAMED_WITH_ARGS(),
143+
ZEND_TYPE_NAMED_WITH_ARGS().
144+
. New compiler-globals fields: CG(type_arg_depth) (right-angle
145+
split state used by the zendlex wrapper), CG(token_residual)
146+
(single-token pushback slot), and CG(generic_scope) (linked
147+
stack of in-scope type parameters).
148+
. New T_TURBOFISH lexer token (literal `::<`). The zendlex wrapper
149+
splits T_SR (`>>`), T_IS_GREATER_OR_EQUAL (`>=`), and T_SR_EQUAL
150+
(`>>=`) into separate `>` tokens whenever CG(type_arg_depth) is
151+
non-zero, with a single-token pushback slot.
152+
. Module API bumped to 20260506; extension API bumped to
153+
420260506. All extensions must be recompiled.
106154

107155
========================
108156
2. Build system changes

0 commit comments

Comments
 (0)