Repository navigation
Full detail lives in the docs and CHANGELOG.
⚠️ Breaking changes
- Variance markers are now
out T/in T(was+T/-T) — rewrite+T→out T,
-T→in T. Old source fails with a migration error. See variance. - A
finalvariant class is rejected — a covariant/contravariant class can't anchor the
extendsedge. Removefinalfrom variant templates. - Variant constructor params keep their real type (no longer erased to
mixed), so
construction is runtime-type-checked.
New features
xphp check— validate-in-CI without emitting; collects every problem in one pass
(text/json/githubrenderers) and runs your PHPStan over the compiled output.compilegates by default — runs the same validators + PHPStan before emitting;
--no-checkfor a fast iteration build.Closure(...)signature types — typed-closure hints, conformance-checked and erased to
\Closure. See closure types.xphp.jsonmanifest — declare source roots / output / hash length for multi-root builds.- Element-typed methods on covariant collections — a method-generic bound grounded on the
enclosing class parameter (contains<U : E>). See type bounds. - Generic methods through inheritance — turbofish on a subclass receiver (instance, static,
nullsafe); an unresolved turbofish is now a compile error. - Variance refinements —
out T/in Ton private properties; by-reference params are
invariant.
Bug fixes
- Turbofish on an undeterminable receiver is rejected instead of emitting a runtime fatal.
- A sibling-referencing class bound (
class Pair<T, U : T>) is grounded correctly. - A scalar bound (
int,string, …) is no longer flagged as an undeclared type.