gleam-lang/gleam · error

empty bit array test

Error message

empty bit array test

What it means

Panic when starting a bit-array decision node with no existing choices: the pivot test is taken from the front of the pending `tests` deque, and this `expect` fires when that deque is empty. The invariant is that any branch reaching bit-array compilation has at least one pending bit-array segment test.

Solutions

  1. Ensure at least one value test is generated per bit-array pattern; if a pattern has no tests, treat it as a catch-all instead of entering the pivot path.
  2. Fix segment lowering so trivially-true segments do not push empty test lists while still entering this compiler path.
  3. Short-circuit: if `tests` is empty, add the branch as unconditional rather than selecting a pivot.

Example fix

// before
let test = tests.front().expect("empty bit array test").clone();
// after
let Some(test) = tests.front() else {
    panic!("bit array pattern produced no tests; cannot choose pivot")
};
let test = test.clone();
Defensive patterns

Strategy: validation

Validate before calling

if tests.is_empty() {
    // no pivot possible: treat pattern as unconditional/catch-all and skip pivot selection
}

Type guard

fn has_pivot_test(tests: &VecDeque<BitArrayTest>) -> bool { !tests.is_empty() }

Try / catch

std::panic::catch_unwind(|| compile_bit_array_node(node)).map_err(|_| Bug::EmptyBitArrayTest)

Prevention

When it happens

Trigger: Compiling a case subject with bit-array patterns where all pending tests were already consumed (e.g. empty segment list, or every branch's first segment produced no test), so `tests.front()` is None at the pivot-selection point.

Common situations: Gleam compiler contributors hit this with bit-array patterns containing only size/width segments without value tests, or after changes to how bit-array segment tests are generated (`is_bit_array_test`/segment lowering).

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of gleam-lang/gleam@49f8762da5 (2026-09-14). Data as JSON: /api/errors/ac9e140541fb3492. Report an issue: GitHub.

Appendix: source

Thrown at compiler-core/src/exhaustiveness.rs:3213

    /// One path is going to be for the branches that can match if the test is
    /// successful, and the other one is going to be the usual fallback to go
    /// down to if it's not successful.
    ///
    /// > "And now for the tricky bit..."
    /// > <https://youtu.be/lKXe3HUG2l4?si=i1thYB-kjfMU8NSe&t=645>
    ///
    fn add_checked_bit_array_branch(
        &mut self,
        pattern_check: PatternCheck,
        mut tests: VecDeque<BitArrayTest>,
        mut branch: Branch,
        compiler: &mut Compiler<'_>,
    ) {
        // If we haven't found a test yet we just use the first one we find
        // as the pivot to split all the branches.
        let pivot_test = match self.choices.as_slice() {
            [] => {
                let test = tests.front().expect("empty bit array test").clone();
                self.choices.push((
                    RuntimeCheck::BitArray { test: test.clone() },
                    VecDeque::new(),
                ));
                test
            }
            [(RuntimeCheck::BitArray { test }, _)] => test.clone(),
            _ => unreachable!("non bit array check when splitting bit array patterns"),
        };

        let pattern_fails_if_test_succeeds = tests
            .iter()
            .any(|test| test.fails_if_succeeding(&pivot_test).is_certain());

        let pattern_fails_if_test_fails = tests
            .iter()
            .any(|test| test.fails_if_failing(&pivot_test).is_certain());

View on GitHub (pinned to 49f8762da5)