{"record":{"id":"c82aec21cf2e8d00","repo":"gleam-lang/gleam","slug":"tried-to-reduce-without-2-guards","errorCode":null,"errorMessage":"Tried to reduce without 2 guards","messagePattern":"Tried to reduce without 2 guards","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler-core/src/parse.rs","lineNumber":5145,"sourceCode":"/// Simple-Precedence-Parser, perform reduction for expression\nfn do_reduce_expression(operator: Spanned, estack: &mut Vec<UntypedExpr>) {\n    match (estack.pop(), estack.pop()) {\n        (Some(right), Some(left)) => {\n            let new_expression = expression_operator_reduction(operator, left, right);\n            estack.push(new_expression);\n        }\n        _ => panic!(\"Tried to reduce without 2 expressions\"),\n    }\n}\n\n/// Simple-Precedence-Parser, perform reduction for clause guard\nfn do_reduce_clause_guard(operator: Spanned, estack: &mut Vec<UntypedClauseGuard>) {\n    match (estack.pop(), estack.pop()) {\n        (Some(right), Some(left)) => {\n            let expression = clause_guard_reduction(operator, left, right);\n            estack.push(expression);\n        }\n        _ => panic!(\"Tried to reduce without 2 guards\"),\n    }\n}\n\n/// Simple-Precedence-Parser, perform reduction for clause guard\nfn do_reduce_constant(operator: Spanned, estack: &mut Vec<UntypedConstant>) {\n    match (estack.pop(), estack.pop()) {\n        (Some(left), Some(right)) => {\n            let new_expression = constant_binop_reduction(operator, right, left);\n            estack.push(new_expression);\n        }\n        _ => panic!(\"Tried to reduce without 2 guards\"),\n    }\n}\n\n/// Simple-Precedence-Parser, perform reduction for bit array size expressions\nfn reduce_bit_array_size((_, token, _): Spanned, experession_stack: &mut Vec<BitArraySize<()>>) {\n    let operator = token_to_bit_array_size_operator(&token)\n        .expect(\"only operator tokens are pushed onto the bit array size opstack\");","sourceCodeStart":5127,"sourceCodeEnd":5163,"githubUrl":"https://github.com/gleam-lang/gleam/blob/15b07c783065c92bb016b1b74ed0995a5259850f/compiler-core/src/parse.rs#L5127-L5163","documentation":"Same invariant as the expression reducer but for clause guards: `do_reduce_clause_guard` requires exactly two guard operands to combine with an operator. Fewer than two indicates the guard parser's stack bookkeeping broke, so it panics.","triggerScenarios":"A clause-guard operator (e.g. `&&`, `||`, comparisons inside a `case` guard) is reduced while the guard stack contains fewer than two `UntypedClauseGuard` values, due to a guard-parsing bug or internals misuse.","commonSituations":"Gleam parser development/regressions around `case` expression guards; not normally triggerable by well-formed or even straightforwardly malformed user code.","solutions":["Extract the failing `case` clause guard into a minimal repro and file a Gleam compiler bug.","When patching the parser, ensure guard operators always follow two pushed guards before reduction.","Work around by rewriting the guard (e.g. splitting a compound guard into simpler ones or using a `let assert` / body-level check)."],"exampleFix":"// before (suspect guard)\ncase x { y if > 3 -> ... }\n// after\ncase x { y if y > 3 -> ... }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let parsed = std::panic::catch_unwind(|| parse_case(tokens));\nmatch parsed {\n    Ok(case) => case,\n    _ => report_compiler_bug(\"Tried to reduce without 2 guards\"),\n}","preventionTips":["Write guards with explicit operands (e.g. `x if x > 3`) rather than unusual operand/operator orders.","Report minimal failing `case` guards as compiler bugs.","Keep guard parser push/pop pairs verified when editing parse.rs."],"tags":["parser","panic","clause-guard","internal-invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"15b07c783065c92bb016b1b74ed0995a5259850f","analyzedAt":"2026-09-14T11:14:59.388Z","contentChangedAt":"2026-09-14T11:14:59.388Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}