gleam-lang/gleam · error

unexpected segment value pattern

Error message

unexpected segment value pattern {pattern:?}

What it means

Panic raised when computing the matched value of a bit array segment (compiler-core/src/exhaustiveness.rs:3903). Bit array sizes/segment values may only be literal-like patterns (ints, strings, variables, wildcards, bit array sizes); whole composite patterns such as `Constructor`, `List`, `Tuple`, `BitArray`, `StringPrefix`, `BitArraySize`-mismatch, or `Invalid` reaching this function violate the compiler's invariants, so it panics with the pattern dump.

Solutions

  1. Rewrite the pattern so segment sizes/values are plain literals, variables, or bit array size expressions (`size(n)`, `size(2 * n)`).
  2. Ensure the program type-checks cleanly — an `Invalid` pattern reaching codegen means an earlier error was suppressed; fix the reported type errors first.
  3. Upgrade the compiler; if reproducible on a supported release, file a bug with the `{pattern:?}` dump and minimal repro.
  4. Compiler contributors: extend the match arms or reject the pattern in validation before this function runs.

Example fix

// before: composite pattern in size slot
let <<x:size(maybe_size)>> = bits  // maybe_size: Result(Int, _)
// after: resolve the size first
assert Ok(n) = maybe_size
let <<x:size(n)>> = bits
Defensive patterns

Strategy: type-guard

Validate before calling

// ensure segment values are literal/variable patterns before value computation
if !matches!(pattern, ast::Pattern::Int(_) | ast::Pattern::String(_) | ast::Pattern::Variable(_) | ast::Pattern::Discard(_) | ast::Pattern::BitArraySize(_) | ast::Pattern::Float(_)) {
    return Err(Error::UnsupportedSegmentPattern);
}

Type guard

fn is_segment_value_pattern(p: &ast::Pattern) -> bool {
    matches!(p, ast::Pattern::Int(_) | ast::Pattern::Float(_) | ast::Pattern::String(_) | ast::Pattern::Variable(_) | ast::Pattern::Discard(_) | ast::Pattern::BitArraySize(_))
}

Prevention

When it happens

Trigger: A bit array segment size or value position contains a pattern other than the allowed literal/variable forms after earlier phases — e.g. a constructor or list pattern in a size slot — usually because type checking failed to reject the program or a compiler change altered pattern classification.

Common situations: Compiler developers working on bit array size expressions; users of patched compilers or pre-release builds compiling patterns like `<<x:size(Some(n))>>`; stable-release users should never see this.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

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

        }
        ast::Pattern::String { value, .. } => BitArrayMatchedValue::LiteralString {
            value: value.clone(),
            encoding: StringEncoding::Utf8,
            bytes: convert_string_escape_chars(value).as_bytes().into(),
        },
        ast::Pattern::Variable { name, .. } => BitArrayMatchedValue::Variable(name.clone()),
        ast::Pattern::Discard { name, .. } => BitArrayMatchedValue::Discard(name.clone()),
        ast::Pattern::Assign { name, pattern, .. } => BitArrayMatchedValue::Assign {
            name: name.clone(),
            value: Box::new(segment_matched_value(segment, Some(pattern), read_action)),
        },
        ast::Pattern::BitArraySize(_)
        | ast::Pattern::List { .. }
        | ast::Pattern::Constructor { .. }
        | ast::Pattern::Tuple { .. }
        | ast::Pattern::BitArray { .. }
        | ast::Pattern::StringPrefix { .. }
        | ast::Pattern::Invalid { .. } => panic!("unexpected segment value pattern {pattern:?}"),
    }
}

fn int_to_bits(
    value: &BigInt,
    read_size: &ReadSize,
    endianness: Endianness,
    signed: bool,
) -> Result<BitVec<u8, Msb0>, IntToBitsError> {
    let size = read_size
        .constant_bits()
        .ok_or(IntToBitsError::NonConstantSize)?
        .to_u32()
        .ok_or(IntToBitsError::ExceedsMaximumSize)?;

    if !representable_with_bits(value, size, signed) {
        return Err(IntToBitsError::Unrepresentable { size });
    } else if size > BitArrayMatchedValue::MAX_BITS_INTERFERENCE {

View on GitHub (pinned to 49f8762da5)