)]}'
{
  "commit": "55cf8fb38ae30c086458f28daa1e84ba4e24e501",
  "tree": "9d4be7a234b1717a8344591308b83b6199fa2d5e",
  "parents": [
    "47c108de75939137fec1a2c6cd8c60d6ab49feb7"
  ],
  "author": {
    "name": "Aaron Webster",
    "email": "AaronWebster@users.noreply.github.com",
    "time": "Wed Jun 03 22:10:23 2026 -0700"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Wed Jun 03 22:10:23 2026 -0700"
  },
  "message": "Extend switch matcher: disjunction, conjunction, single-entry demotion (#256)\n\nPR 241\u0027s _get_switch_candidate only matched bare \\`discrim \u003d\u003d K\\`\nequalities. Real protocol grammars express the same intent in many\nforms; this PR rewrites the matcher to recognize them all.\n\n_extract_switch_arms decomposes an existence_condition into a\n(discriminant, [(case_value, residual), ...]) tuple, handling:\n\n  * Bare equality (\\`tag \u003d\u003d K\\`) — one arm, no residual.\n  * Disjunction of equalities on a shared discriminant\n    (\\`tag \u003d\u003d A || tag \u003d\u003d B || tag \u003d\u003d C\\`) — one arm per Ki, no\n    residual. Common for tagged unions where several values share a\n    payload. Combined with the identical-body coalescing already in\n    place, this collapses to a single multi-label switch arm.\n  * Conjunction with an equality (\\`tag \u003d\u003d K \u0026\u0026 other_predicate\\`) —\n    one arm carrying \\`[other_predicate]\\` as residual. Useful for\n    nested guards like \\`if outer_flag \u0026\u0026 tag \u003d\u003d K\\`.\n  * Mixed shapes inside a disjunction:\n    \\`(tag \u003d\u003d 0 \u0026\u0026 a) || (tag \u003d\u003d 1 \u0026\u0026 b) || tag \u003d\u003d 2\\` — three arms\n    with respective residuals \\`[a]\\`, \\`[b]\\`, \\`[]\\`.\n\nAn arm with a residual emits the has_\\${field}()-based check as its\ncase body (the residual is folded into the existing accessor) — sound\nand lets the C++ compiler fold the case-pinned discriminant\ncomparison via inlining.\n\nA demotion pass measures total arm-entries per group and falls back\nto ok_method_test when the count is below 2 — without this, a lone\nfield like \\`if outer \u0026\u0026 tag \u003d\u003d K: xc\\` would get wrapped in a one-case\nswitch whose overhead (temporary, Known() guard, scope braces)\nexceeds the dedupe. This also fixes a latent bug introduced when\nrender-dedup was added: the scoped discriminant render mutated\nsubexpressions during the grouping pass, so groups that later got\ndemoted would have left dead \\`const auto \u003d ...\\` definitions in the\nemitted Ok(). The scoped render now happens at emit time, only for\nsurviving groups.\n\nThe benchmark schema gains a DisjunctionConditionals struct\nexercising three \\`||\\` chains (2, 3, 3 labels) and the benchmark TU\ngains a runtime test for it. Golden churn: many_conditionals.emb.h\ngains the new struct\u0027s output; condition.emb.h and virtual_field.emb.h\nshrink because several BasicConditional-style structs had a lone xc\nfield that PR 241 was wrapping in a one-arm switch — demotion brings\nthem back to the cheaper has_xc() check.",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "9322e1f84d368d35776525afdaa2b1386323662d",
      "old_mode": 33188,
      "old_path": "compiler/back_end/cpp/header_generator.py",
      "new_id": "b3305d31988256e4c8fd5cd350f1e0f7b88ac801",
      "new_mode": 33188,
      "new_path": "compiler/back_end/cpp/header_generator.py"
    },
    {
      "type": "modify",
      "old_id": "deb4f2f969a452aa7ed54401aedee7311d6eadab",
      "old_mode": 33188,
      "old_path": "compiler/back_end/cpp/testcode/many_conditionals_benchmark.cc",
      "new_id": "a123a188c6ab14d970e7a644f53c70225bd430b0",
      "new_mode": 33188,
      "new_path": "compiler/back_end/cpp/testcode/many_conditionals_benchmark.cc"
    },
    {
      "type": "modify",
      "old_id": "53c476b04a38108f2e959a83c929239ce30a9177",
      "old_mode": 33188,
      "old_path": "testdata/golden_cpp/condition.emb.h",
      "new_id": "f1111d519954bf3dfe46fd4e852888bc6ce20b84",
      "new_mode": 33188,
      "new_path": "testdata/golden_cpp/condition.emb.h"
    },
    {
      "type": "modify",
      "old_id": "ba120fb402c8eade9f461d1803ce641bcfa17482",
      "old_mode": 33188,
      "old_path": "testdata/golden_cpp/many_conditionals.emb.h",
      "new_id": "8f5fef0544e3b9a01aed7f64a1fc8db0ffe8c031",
      "new_mode": 33188,
      "new_path": "testdata/golden_cpp/many_conditionals.emb.h"
    },
    {
      "type": "modify",
      "old_id": "26bfde71c0eabed0b65f3fe501d09d42f408631f",
      "old_mode": 33188,
      "old_path": "testdata/golden_cpp/virtual_field.emb.h",
      "new_id": "e78af9bf0ca8039b66336bee189048cae0fdf66d",
      "new_mode": 33188,
      "new_path": "testdata/golden_cpp/virtual_field.emb.h"
    },
    {
      "type": "modify",
      "old_id": "f18143448a98947bc928bfa4813f95a57c1523ea",
      "old_mode": 33188,
      "old_path": "testdata/many_conditionals.emb",
      "new_id": "de7f18aea84ccc86b543df028f78eb2cdce56f33",
      "new_mode": 33188,
      "new_path": "testdata/many_conditionals.emb"
    }
  ]
}
