gleam-lang/gleam · error

aliased non constant value

Error message

aliased non constant value: {value:#?}

What it means

This is an internal compiler panic raised in `assign_segment_constant_value` (compiler-core/src/exhaustiveness.rs:486). While computing bindings for a bit array segment pattern, only literal string segments carry a constant value that can be bound to an alias. If the matched value is a `Variable`, `Discard`, or `Assign` variant, no constant exists to alias, and the compiler asserts this invariant with a panic. Hitting it means the pattern-computation phases produced a shape that constant-binding was not designed to accept.

Solutions

  1. Reduce the failing bit array pattern to a minimal snippet and file a bug at the gleam compiler repository with the panic debug dump (`{value:#?}`) and the source pattern.
  2. Check your compiler version; upgrade to the latest release where the pattern-computation bug may already be fixed.
  3. Temporarily rewrite the pattern to avoid aliasing the non-literal segment (e.g. match the segment separately) to unblock compilation.
  4. If building a patched compiler, audit the code that constructs `BitArrayMatchedValue` for segment binding so only `LiteralString` values reach `assign_segment_constant_value`.

Example fix

// before (source pattern that may trigger via compiler bug)
case bits { <<"lit":utf8>> <> rest -> ... }
// after: split binding out if the compiler panics
let <<"lit":utf8>> = prefix
let rest = remainder
Defensive patterns

Strategy: type-guard

Validate before calling

// only alias constant segment values
if !matches!(value, BitArrayMatchedValue::LiteralString { .. }) {
    return Err(...); // or handle Variable/Discard/Assign explicitly
}

Type guard

fn is_constant_value(v: &BitArrayMatchedValue) -> bool {
    matches!(v, BitArrayMatchedValue::LiteralString { .. })
}

Prevention

When it happens

Trigger: Compiling a `<<..>>` bit array pattern where a segment binds a name (`alias = pattern`) but the resolved `BitArrayMatchedValue` is `Variable`, `Discard`, or `Assign` instead of a `LiteralString`; this only occurs if upstream match-value computation misclassifies the segment, e.g. after a compiler regression or when using nightly/patched builds with custom pattern handling.

Common situations: Gleam compiler contributors testing changes to bit array pattern matching; users building a modified fork or hitting a compiler bug on exotic bit array patterns like `<<x:size(n)>>` with aliases in case expressions; generally not reachable from valid user code on a stable release.

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/fe9679771dd1f2a6. Report an issue: GitHub.

Appendix: source

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

            segment_name,
            BoundValue::BitArraySlice {
                bit_array,
                read_action: value,
            },
        ));
    }

    fn assign_segment_constant_value(&mut self, name: EcoString, value: &BitArrayMatchedValue) {
        let value = match value {
            BitArrayMatchedValue::LiteralFloat(value) => BoundValue::LiteralFloat(value.clone()),
            BitArrayMatchedValue::LiteralInt { value, .. } => BoundValue::LiteralInt(value.clone()),
            BitArrayMatchedValue::LiteralString { value, .. } => {
                BoundValue::LiteralString(value.clone())
            }
            BitArrayMatchedValue::Variable(_)
            | BitArrayMatchedValue::Discard(_)
            | BitArrayMatchedValue::Assign { .. } => {
                panic!("aliased non constant value: {value:#?}")
            }
        };

        self.bindings.push((name, value));
    }
}

/// A user defined pattern such as `Some((x, 10))`.
/// This is a bit simpler than the full fledged `TypedPattern` used for code analysis
/// and only focuses on the relevant bits needed to perform exhaustiveness checking
/// and code generation.
///
/// Using this simplified version of a pattern for the case compiler makes it a
/// whole lot simpler and more efficient (patterns will have to be cloned, so
/// we use an arena to allocate those and only store ids to make this operation
/// extra cheap).
///
#[derive(Clone, Eq, PartialEq, Debug)]

View on GitHub (pinned to 49f8762da5)