Repository navigation
Classify a quoted condition as a conditional operand - #1577
Merged
Merged
Conversation
`||` is the logical OR for conditions and the string concatenation otherwise. The overloads told them apart by the raw operand types, so a `c()`-quoted condition never counted as a condition: `c(cond1) || c(cond2)` built a concatenation where `cond1 || cond2` builds an OR. Classify the operands after unwrapping them, as the node built from them holds them. Co-Authored-By: Claude Opus 5.5
Instead of unwrapping in the `||` overloads, let the operand axis classify the quoting wrapper, as the vocabulary layer intends for operand-only nodes: `is_conditional_operand_v` becomes an open trait like `is_operator_argument_v`, the `condition_t` base rule is its specialization in `tags.h`, and `quoted_expression.h` classifies a quoted operand as the operand it quotes. The `||` overloads ask the trait about their operands again, as before. Co-Authored-By: Claude Opus 5.5
|| apart by its unwrapped operands
trueqbit
marked this pull request as ready for review
October 8, 2026 10:42
fnc12
approved these changes
Oct 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #1564: based on its branch, so this diff shows only the changes on top of it.
Summary
||is the logical OR for conditions and the string concatenation otherwise. The twooperator||overloads told them apart by the raw operand types, andquoted_expression_tis not a condition, so ac()-quoted condition always took the concatenation:That contradicts what #1564 establishes: a node built from
c(x)is the very node built fromx. A quoted condition is now classified as a conditional operand:c(cond1) || c(cond2),c(cond1) || cond2andcond1 || c(cond2)now all build the OR thatcond1 || cond2builds.Only
||needed this: it is the one overloaded operator with two meanings.&&accepts any operator argument and already built anand_condition_tfrom quoted conditions.The classification lives on the operand axis, not in the
||overloads, as the vocabulary layer intends for an operand-only node such as the quoting wrapper:is_conditional_operand_vbecomes an open trait with a SFINAE slot, likeis_operator_argument_v(vocabulary/traits/operand_traits_fwd.h);condition_tbase rule is now a specialization intags.h, so every node inheritingcondition_tis classified as before;ast/quoted_expression.hclassifies a quoted operand as the operand it quotes, next to itsis_operator_argument_vspecialization.The
||overloads are unchanged; they ask the trait about their operands as before. The other operand traits (arithmetic, negatable, chainable) are left as they are: a quoted operand already passes wherever they are checked, viais_operator_argument.Consumer-visible change
Code that relied on
c(cond1) || c(cond2)concatenating two conditions now gets their OR. Concatenating conditions on purpose remains available explicitly asconc(cond1, cond2). Concatenation of non-conditions, e.g.c(&User::name) || "a", is unchanged.This is also half of the trap reported in #1575 (
c(match<Post>("cat")) || c(match<Post>("dog"))serializing||); the other half,match()results not being conditions at all, follows in a separate PR stacked on this one.Test plan
tests/static_tests/quoted_operands.cpp, new section "logical or concatenation":c(cond1) || c(cond2),c(cond1) || cond2andcond1 || c(cond2)have the type ofcond1 || cond2, anor_condition_t;c(cond1) && c(cond2)has the type ofcond1 && cond2;is_conditional_operandholds forc(cond1), and not forc(&User::name);c(&User::name) || "a"andc(&User::name) || c("a")still build aconc_t.🤖 Generated with Claude Code