This PR was squashed before being merged into the 3.x branch.
Discussion
----------
Reject template wrappers from another environment
Twig now rejects `TemplateWrapper` instances created by another `Environment`.
This prevents templates from unexpectedly using another environment's loader, extensions, globals, or sandbox policy.
Commits
-------
83e8f7e123 Reject cross-environment template wrappers in block chains
c1fc112047 Reject cross-environment template wrappers
* 3.x:
Clarify the exception message for nested block chains from another environment
Report a clear error when using macros imported in a template body that was not rendered
# Conflicts:
# CHANGELOG
# src/Template.php
# tests/CallMacroTest.php
This PR was merged into the 3.x branch.
Discussion
----------
Report a clear error when using macros imported in a template body that was not rendered
Commits
-------
72c2f669bd Report a clear error when using macros imported in a template body that was not rendered
* 3.x:
Resolve block chains against the render context instead of freezing lineages
Resolve constant parent templates once instead of on every lookup
Template runtime and block composition
Fix wrapping the Twig cache pool in a second tag aware adapter
Check that the use tag is allowed before resolving trait templates
# Conflicts:
# CHANGELOG
# extra/twig-extra-bundle/TwigExtraBundle.php
# src/Template.php
This PR was merged into the 3.x branch.
Discussion
----------
Check that the use tag is allowed before resolving trait templates
Commits
-------
18863f0371 Check that the use tag is allowed before resolving trait templates
* 3.x: (26 commits)
Remove the documentation comments compilation overhead
Clarify source function trust requirements
Throw on PCRE errors in the matches operator
Document that reusing a non-rewindable iterator after destructuring is unsupported
Release destructuring temporaries after assignment
Deprecate prefixed macro definedness checks
Fix duplicate macro deprecation wording
Throw when list formatting fails
Document that sequence destructuring consumes one value per pattern slot
Fix the html_attr documentation about iterables in data attributes
Warn about untrusted input with the default Tempest markdown converter
Document that overriding MacroNode::compile() is not supported anymore
Merge overlapping CHANGELOG entries for the destructuring fatal error fix
Document that include_only keeps global variables available
Remove lazy macro import resolution
Honor date formatter prototype calendars
Fix Stringable keys for ArrayAccess implementations
Fix repeated object destructuring evaluation
Restore void return type compatibility for extension points
Reject destructuring patterns containing no variables
...
# Conflicts:
# CHANGELOG
# doc/deprecated.rst
# doc/filters/format_datetime.rst
# extra/twig-extra-bundle/DependencyInjection/Compiler/MissingExtensionSuggestorPass.php
# extra/twig-extra-bundle/DependencyInjection/TwigExtraExtension.php
# extra/twig-extra-bundle/TwigExtraBundle.php
# src/MacroNamespace.php
# src/Node/MacrosNode.php
# src/Parser.php
# src/Test/IntegrationTestCase.php
# src/Test/NodeTestCase.php
# tests/CallMacroTest.php
# tests/ExpressionParserTest.php
# tests/Fixtures/macros/duplicate_definition.legacy.test
# tests/Node/MacrosTest.php
# tests/ParserTest.php
This PR was squashed before being merged into the 3.x branch.
Discussion
----------
Remove the documentation comments compilation overhead
Documentation comments are now attached to semantic nodes during parsing, removing the dedicated AST traversal. Token parsers returning placeholder nodes can select the semantic documentation target.
Commits
-------
60eed4ccd5 Remove the documentation comments compilation overhead
This PR was merged into the 3.x branch.
Discussion
----------
Release destructuring temporaries after assignment
The compiled destructuring code kept the right-hand side alive in a hidden local until the end of rendering, wasting memory on large arrays and iterators. The temporary is now cleared as part of the compiled expression.
The way it works:
For this Twig expression:
```twig
{% do {name, email: address} = user %}
```
The previous generated expression was conceptually:
```php
[$context["name"], $context["address"]] = [
getAttribute($_v0 = $context["user"], "name"),
getAttribute($_v0, "email"),
];
```
The branch now generates:
```php
[
[$context["name"], $context["address"]] = [
getAttribute($_v0 = $context["user"], "name"),
getAttribute($_v0, "email"),
],
$_v0 = null,
][0]
```
The important wrapper is:
```php
[$originalExpression, $_v0 = null][0]
```
PHP evaluates array elements from left to right:
1. The original destructuring assignment runs.
2. The temporary variable is set to `null`, releasing its reference.
3. `[0]` returns the result of the original expression.
This preserves Twig’s rule that a destructuring expression returns its right-hand value.
Commits
-------
c459ef0bdd Release destructuring temporaries after assignment
This PR was merged into the 3.x branch.
Discussion
----------
Deprecate prefixed macro definedness checks
Testing a macro through a legacy `macro_`-prefixed name would have silently returned `false` in Twig 4.0 without ever warning; `has()` now triggers the same deprecation as `call()`.
Commits
-------
977aef7172 Deprecate prefixed macro definedness checks
This PR was squashed before being merged into the 3.x branch.
Discussion
----------
Fix Stringable keys for ArrayAccess implementations
This restores support for `Stringable` keys on string-keyed `ArrayAccess` implementations such as `ArrayObject` and `ArrayIterator`, while preserving object keys for `SplObjectStorage`.
The object key is attempted first and is converted to a string only when the implementation rejects it. The optimized and strict lookup paths now share the same behavior without duplicate existence checks.
Commits
-------
f3f1649955 Fix Stringable keys for ArrayAccess implementations
Sequence destructuring compiled its right-hand side straight into
array_pad(), which throws "Argument #1 must be of type array" when a
Traversable is provided:
{% do [a, b] = items %}
with an IteratorAggregate/Generator for items crashed with a TypeError.
Coerce Traversables via iterator_to_array() before padding, matching
the behavior of the spread, merge, and slice operations which already
accept Traversables.