From 4d5d233776d840b6272d7b94e85e459d804f35d3 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 22 Sep 2026 21:30:14 +0100 Subject: [PATCH] Compile the generator guard as an unreachable yield instead of a yield from --- CHANGELOG | 1 + src/Node/BlockNode.php | 2 +- src/Node/CaptureNode.php | 2 +- src/Node/ModuleNode.php | 2 +- tests/Node/BlockTest.php | 2 +- tests/Node/MacroTest.php | 4 ++-- tests/Node/MacrosTest.php | 2 +- tests/Node/ModuleTest.php | 2 +- tests/Node/SetTest.php | 4 ++-- 9 files changed, 11 insertions(+), 10 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index de9dd304e..fdf14d885 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ * Fix the escaping safe analysis retaining every compiled template node for the lifetime of the environment * Speed up loading a template that the environment has already loaded + * Speed up rendering by compiling a cheaper generator guard into templates * Fix `IntlExtension` letting the pattern derived from a date formatter prototype override an explicit locale * Fix `IntlExtension` not honoring the locale of a date formatter prototype configured with no date and time styles * Speed up macro calls diff --git a/src/Node/BlockNode.php b/src/Node/BlockNode.php index b4f939cf6..b736b2d4c 100644 --- a/src/Node/BlockNode.php +++ b/src/Node/BlockNode.php @@ -42,7 +42,7 @@ class BlockNode extends Node $compiler ->subcompile($this->getNode('body')) - ->write("yield from [];\n") + ->write("return; yield;\n") ->outdent() ->write("}\n\n") ; diff --git a/src/Node/CaptureNode.php b/src/Node/CaptureNode.php index 3b7f0b6d8..2f4ef5a79 100644 --- a/src/Node/CaptureNode.php +++ b/src/Node/CaptureNode.php @@ -39,7 +39,7 @@ class CaptureNode extends Node ->raw("(function () use (&\$context, \$macros, \$blocks) {\n") ->indent() ->subcompile($this->getNode('body')) - ->write("yield from [];\n") + ->write("return; yield;\n") ->outdent() ->write('})()') ; diff --git a/src/Node/ModuleNode.php b/src/Node/ModuleNode.php index 5c27a10ea..8f2283475 100644 --- a/src/Node/ModuleNode.php +++ b/src/Node/ModuleNode.php @@ -379,7 +379,7 @@ final class ModuleNode extends Node implements CoercesChildrenToStringInterface $compiler->subcompile($this->getNode('display_end')); if (!$this->hasNode('parent')) { - $compiler->write("yield from [];\n"); + $compiler->write("return; yield;\n"); } $compiler diff --git a/tests/Node/BlockTest.php b/tests/Node/BlockTest.php index 8606484ba..0006fb16e 100644 --- a/tests/Node/BlockTest.php +++ b/tests/Node/BlockTest.php @@ -49,7 +49,7 @@ public function block_foo(array \$context, array \$blocks = []): iterable { \$macros = \$this->macros; yield "foo"; - yield from []; + return; yield; } EOF, new Environment(new ArrayLoader()), ]; diff --git a/tests/Node/MacroTest.php b/tests/Node/MacroTest.php index 29a0b5cd8..08940c845 100644 --- a/tests/Node/MacroTest.php +++ b/tests/Node/MacroTest.php @@ -77,7 +77,7 @@ new \\Twig\\TwigMacro("foo", function (\$foo = null, \$bar = "Foo", \$_underscor return ('' === \$tmp = implode('', iterator_to_array((function () use (&\$context, \$macros, \$blocks) { yield "foo"; - yield from []; + return; yield; })(), false))) ? '' : new Markup(\$tmp, \$this->env->getCharset()); }, ["foo" => true, "bar" => true, "_underscore" => true], false) EOF, new Environment(new ArrayLoader(), ['use_yield' => true]), @@ -98,7 +98,7 @@ new \\Twig\\TwigMacro("foo", function (\$foo = null, \$bar = "Foo", \$_underscor return ('' === \$tmp = \\Twig\\Extension\\CoreExtension::captureOutput((function () use (&\$context, \$macros, \$blocks) { yield "foo"; - yield from []; + return; yield; })())) ? '' : new Markup(\$tmp, \$this->env->getCharset()); }, ["foo" => true, "bar" => true, "_underscore" => true], false) EOF, new Environment(new ArrayLoader(), ['use_yield' => false]), diff --git a/tests/Node/MacrosTest.php b/tests/Node/MacrosTest.php index 7a5687e69..1d2687027 100644 --- a/tests/Node/MacrosTest.php +++ b/tests/Node/MacrosTest.php @@ -74,7 +74,7 @@ protected function loadDeclaredMacros(): array return ('' === \$tmp = implode('', iterator_to_array((function () use (&\$context, \$macros, \$blocks) { yield "foo"; - yield from []; + return; yield; })(), false))) ? '' : new Markup(\$tmp, \$this->env->getCharset()); }, ["foo" => true], false), ]; diff --git a/tests/Node/ModuleTest.php b/tests/Node/ModuleTest.php index 670309367..8988eef83 100644 --- a/tests/Node/ModuleTest.php +++ b/tests/Node/ModuleTest.php @@ -159,7 +159,7 @@ class __TwigTemplate_%x extends Template \$macros = \$this->macros; // line 1 yield "foo"; - yield from []; + return; yield; } /** diff --git a/tests/Node/SetTest.php b/tests/Node/SetTest.php index 4cfd85aca..4230578ee 100644 --- a/tests/Node/SetTest.php +++ b/tests/Node/SetTest.php @@ -65,7 +65,7 @@ EOF // line 1 \$context["foo"] = ('' === \$tmp = implode('', iterator_to_array((function () use (&\$context, \$macros, \$blocks) { yield "foo"; - yield from []; + return; yield; })(), false))) ? '' : new Markup(\$tmp, \$this->env->getCharset()); EOF, new Environment(new ArrayLoader(), ['use_yield' => true]), ]; @@ -74,7 +74,7 @@ EOF, new Environment(new ArrayLoader(), ['use_yield' => true]), // line 1 $context["foo"] = ('' === $tmp = \Twig\Extension\CoreExtension::captureOutput((function () use (&$context, $macros, $blocks) { yield "foo"; - yield from []; + return; yield; })())) ? '' : new Markup($tmp, $this->env->getCharset()); EOF, new Environment(new ArrayLoader(), ['use_yield' => false]), ];