From b430b401acc8d671d8cc00a8106aa8d16a1e7f97 Mon Sep 17 00:00:00 2001 From: Adam Danielsson Date: Mon, 13 Jul 2026 20:54:13 +0200 Subject: [PATCH] Fix `and` operator to return operands, not bools `and` coerced its result to a bool instead of returning the operand, unlike `or`. This breaks the `(cond and x) or y` value idiom, which renders True/False instead of x/y. Mirror the `or` branch so `and` matches Jinja2/Python short-circuit semantics. --- include/minja/minja.hpp | 4 ++-- tests/test-syntax.cpp | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/minja/minja.hpp b/include/minja/minja.hpp index 5ed0556..b8fb644 100644 --- a/include/minja/minja.hpp +++ b/include/minja/minja.hpp @@ -1356,8 +1356,8 @@ class BinaryOpExpr : public Expression { } if (op == Op::And) { - if (!l.to_bool()) return Value(false); - return right->evaluate(context).to_bool(); + if (!l.to_bool()) return l; + return right->evaluate(context); } else if (op == Op::Or) { if (l.to_bool()) return l; return right->evaluate(context); diff --git a/tests/test-syntax.cpp b/tests/test-syntax.cpp index 36bdaa3..376c755 100644 --- a/tests/test-syntax.cpp +++ b/tests/test-syntax.cpp @@ -494,6 +494,9 @@ TEST(SyntaxTest, SimpleCases) { EXPECT_EQ( "2; ; 10", render(R"({{ {1: 2}.get(1) }}; {{ {}.get(1) or '' }}; {{ {}.get(1, 10) }})", {}, {})); + EXPECT_EQ( + "def; ; A; B", + render(R"({{ 'abc' and 'def' }}; {{ '' and 'x' }}; {{ (true and 'A') or 'B' }}; {{ (false and 'A') or 'B' }})", {}, {})); EXPECT_EQ( R"(1,1.2,"a",true,true,false,false,null,[],[1],[1, 2],{},{"a": 1},{"1": "b"},)", render(R"(