feature #4873 Deprecate duplicate macro definitions (fabpot)

This PR was merged into the 3.x branch.

Discussion
----------

Deprecate duplicate macro definitions

Commits
-------

258089b8a6 Deprecate duplicate macro definitions
This commit is contained in:
Fabien Potencier
2026-07-27 12:45:09 +02:00
4 changed files with 25 additions and 0 deletions
+1
View File
@@ -4,6 +4,7 @@
* Add a `format_list` filter to `IntlExtension` to format a list of strings using PHP 8.5's `IntlListFormatter`
* Fix array access with a `Stringable` key coercing the key to string for `ArrayAccess` objects that use object keys (such as `SplObjectStorage`)
* Fix duplicated macro argument names triggering a PHP fatal error instead of a `SyntaxError`
* Deprecate defining a macro more than once in the same template
# 3.28.0 (2026-07-03)
+7
View File
@@ -306,6 +306,13 @@ Templates
deprecated as of Twig 3.28 and will throw in Twig 4.0. These tags have a
global effect on the template and must be declared at the root of its body.
Macros
------
* Defining a macro more than once in the same template is deprecated as of Twig
3.29 and will throw a ``SyntaxError`` in Twig 4.0. Give each macro a unique
name.
Filters
-------
+4
View File
@@ -303,6 +303,10 @@ class Parser
public function setMacro(string $name, MacroNode $node): void
{
if (isset($this->macros[$name])) {
trigger_deprecation('twig/twig', '3.29', 'Defining the macro "%s" more than once in "%s" is deprecated and will throw a SyntaxError in Twig 4.0 (first definition at line %d, second at line %d).', $name, $this->stream->getSourceContext()->getName(), $this->macros[$name]->getTemplateLine(), $node->getTemplateLine());
}
$this->macros[$name] = $node;
}
@@ -0,0 +1,13 @@
--TEST--
Defining a macro more than once is deprecated
--DEPRECATION--
Since twig/twig 3.29: Defining the macro "greet" more than once in "index.twig" is deprecated and will throw a SyntaxError in Twig 4.0 (first definition at line 3, second at line 4).
--TEMPLATE--
{% import _self as macros %}
{% macro greet() %}first{% endmacro %}
{% macro greet() %}second{% endmacro %}
{{ macros.greet() }}
--DATA--
return []
--EXPECT--
second