gleam-lang/gleam · error
bit array compilation with no choice
Error message
bit array compilation with no choice
What it means
Panic after compiling a bit-array pivot test: the code assumes `self.choices` has exactly the one choice pushed for the successful test, so `self.choices.get_mut(0)` must succeed. If choices is empty here, the pivot-test push above did not happen or choices were cleared.
Solutions
- Verify every path that reaches this code pushed the `(RuntimeCheck::BitArray { .. }, ...)` choice first.
- Check early returns above (e.g. already-compiled patterns) do not bypass the pivot push while later code still assumes choice 0 exists.
- Use `let Some((_, branches)) = self.choices.get_mut(0)` with a descriptive panic to ease debugging.
Example fix
// before
let (_, if_true_branches) = self.choices.get_mut(0).expect("bit array compilation with no choice");
// after
let Some((_, if_true_branches)) = self.choices.get_mut(0) else {
panic!("choices empty when adding bit array branch")
}; Defensive patterns
Strategy: validation
Validate before calling
assert!(!self.choices.is_empty(), "pivot test must be pushed before branch compilation");
Type guard
fn first_choice(choices: &Choices) -> Option<&(RuntimeCheck, Branches)> { choices.first() } Try / catch
std::panic::catch_unwind(|| add_bit_array_branch(branch)).map_err(|_| Bug::BitArrayNoChoice)
Prevention
- Always push the (RuntimeCheck::BitArray, ...) choice before compiling branches.
- Check early-return paths do not bypass the pivot push.
- Assert choices.len() == 1 at bit-array node entry in debug builds.
When it happens
Trigger: Compiling the if-true side of a bit-array decision node when `self.choices` is empty — e.g. the pivot test push was skipped, or a previous branch of the compiler removed choices before this point.
Common situations: Hit by Gleam compiler contributors while refactoring the bit-array path of the exhaustiveness compiler, or when early-return paths (like the `add_checked_bit_array_branch` fast path) leave `self.choices` empty.
Related errors
- empty bit array test
- at least one choice
- check to already be a choice
- no unconditional patterns left
- pattern index
AI-assisted analysis of gleam-lang/gleam@49f8762da5 (2026-09-14).
Data as JSON: /api/errors/13e0116d420dafb5.
Report an issue: GitHub.
Appendix: source
Thrown at compiler-core/src/exhaustiveness.rs:3281
BitArrayMatchedValue::LiteralFloat(_)
| BitArrayMatchedValue::LiteralInt { .. }
| BitArrayMatchedValue::LiteralString { .. }
| BitArrayMatchedValue::Discard(_) => {}
}
}
false
});
let variable = &pattern_check.var;
branch.add_check(variable.is(compiler.bit_array_pattern(tests)));
// We know that there's always going to be a single choice for the
// successful check, so we get that and add the branch to it.
let (_, if_true_branches) = self
.choices
.get_mut(0)
.expect("bit array compilation with no choice");
if_true_branches.push_back(branch);
}
// Same goes for the if_false branch: knowing the pivot test has failed
// we only want to keep those branches with a pattern that still have a
// chance to match.
if !pattern_fails_if_test_fails {
// The main difference with the if true case is that we have no way
// of pruning the number of needed tests, so we add this check back
// exactly as it is.
branch.add_check(pattern_check);
self.fallback.push_back(branch);
}
}
fn save_index_of_new_choice(&mut self, kind: RuntimeCheckKind) {
let index = self.choices.len();
match kind {View on GitHub (pinned to 49f8762da5)