Repository: twigphp/Twig (php)

Issue:
Renamed blocks cannot be overwritten
When renaming blocks in the use statement (`{% use "blocks.twig" with bar as baz %}`), the renamed blocks cannot be adjusted/overwritten in the template. Same goes for extenders of this template.

This scenario is not covered [in the docs](https://twig.symfony.com/doc/3.x/tags/use.html) where blocks are only renamed or output but never altered.

### Reproducer
See the following example https://twigfiddle.com/kxljnw:

*main.twig*
```twig
{% use "blocks.twig" with bar as baz %}

{% block foo %}{{ parent() }}+{% endblock %}
{% block baz %}{{ parent() }}+{% endblock %}

{# works as expected #}
{{ block('foo') }}

{# fails #}
{{ block('baz') }}
```

*blocks.twig*
```twig
{% block foo %}Foo{% endblock %}
{% block bar %}Bar{% endblock %}
```

Pull request description:
Fix the possibility to override an aliased block (via use)
Closes #3709

Patch:
diff --git a/CHANGELOG b/CHANGELOG
index bb7d956a..70838965 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,6 @@
 # 3.15.0 (2024-XX-XX)
 
+ * Fix the possibility to override an aliased block (via use)
  * Add template cache hot reload
  * Allow Twig callable argument names to be free-form (snake-case or camelCase) independently of the PHP callable signature
    They were automatically converted to snake-cased before
diff --git a/src/Node/ModuleNode.php b/src/Node/ModuleNode.php
index d2fb216b..f67c3b0e 100644
--- a/src/Node/ModuleNode.php
+++ b/src/Node/ModuleNode.php
@@ -244,7 +244,11 @@ final class ModuleNode extends Node
                         ->string($key)
                         ->raw(\sprintf(']; unset($_trait_%s_blocks[', $i))
                         ->string($key)
-                        ->raw("]);\n\n")
+                        ->raw("]); \$this->traitAliases[")
+                        ->subcompile($value)
+                        ->raw("] = ")
+                        ->string($key)
+                        ->raw(";\n\n")
                     ;
                 }
             }
diff --git a/src/Template.php b/src/Template.php
index 7b3ce816..cb042b59 100644
--- a/src/Template.php
+++ b/src/Template.php
@@ -37,6 +37,7 @@ abstract class Template
     protected $parents = [];
     protected $blocks = [];
     protected $traits = [];
+    protected $traitAliases = [];
     protected $extensions = [];
     protected $sandbox;
 
@@ -477,7 +478,7 @@ abstract class Template
     public function yieldParentBlock($name, array $context, array $blocks = []): iterable
     {
         if (isset($this->traits[$name])) {
-            yield from $this->traits[$name][0]->yieldBlock($name, $context, $blocks, false);
+            yield from $this->traits[$name][0]->yieldBlock($this->traitAliases[$name] ?? $name, $context, $blocks, false);
         } elseif ($parent = $this->getParent($context)) {
             yield from $parent->unwrap()->yieldBlock($name, $context, $blocks, false);
         } else {


Test patch:
diff --git a/tests/Fixtures/tags/use/use_aliased_block_overridden.test b/tests/Fixtures/tags/use/use_aliased_block_overridden.test
new file mode 100644
index 00000000..8396c6f5
--- /dev/null
+++ b/tests/Fixtures/tags/use/use_aliased_block_overridden.test
@@ -0,0 +1,21 @@
+--TEST--
+"use" tag with an overridden block that is aliased
+--TEMPLATE--
+{% use "blocks.twig" with bar as baz %}
+
+{% block foo %}{{ parent() }}+{% endblock %}
+
+{% block baz %}{{ parent() }}+{% endblock %}
+
+{{ block('foo') }}
+{{ block('baz') }}
+--TEMPLATE(blocks.twig)--
+{% block foo %}Foo{% endblock %}
+{% block bar %}Bar{% endblock %}
+--DATA--
+return []
+--EXPECT--
+Foo+
+Bar+
+Foo+
+Bar+