gleam-lang/gleam · error

Failed to split 'a' slice

Error message

Failed to split 'a' slice

What it means

The mirror of error 103: `a.split_last().expect("Failed to split 'a' slice")` inside the same `did_you_mean` loop in `compiler-core/src/error.rs`. The surrounding `while !b.is_empty() && !a.is_empty()` check makes the failure unreachable under correct logic, so this panic acts purely as an internal consistency assertion on slice `a`.

Solutions

  1. Report a compiler bug with reproduction steps if triggered — this is an internal invariant violation
  2. Update to the newest Gleam release before filing, in case the suggestion code was already patched
  3. Harden the helper by returning `None` from `split_last` matches rather than panicking on empty slices

Example fix

// before
let (a_first, a_rest) = a.split_last().expect("Failed to split 'a' slice");
// after
let Some((a_first, a_rest)) = a.split_last() else { return None; };
Defensive patterns

Strategy: fallback

Validate before calling

// defensive pre-condition for library contributors:
debug_assert!(!a.is_empty() && !b.is_empty(), "slices must be non-empty before split_last");

Try / catch

// ICE — no user catch; guard the compiler process invocation:
match std::process::Command::new("gleam").arg("check").status() {
    Ok(s) if s.success() => {},
    _ => eprintln!("gleam check failed or panicked"),
}

Prevention

When it happens

Trigger: `split_last` on an empty `a` despite the loop guard — only possible through an upstream logic bug (e.g. `a` recomputed to empty inside the loop body) or concurrent mutation of the slice between the emptiness check and the split call.

Common situations: Not encountered in normal use; would manifest as a Gleam compiler panic while computing a spelling suggestion for a misspelled import, label, or field name.

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

Appendix: source

Thrown at compiler-core/src/error.rs:830

// https://github.com/rust-lang/rust/blob/03994e498df79aa1f97f7bbcfd52d57c8e865049/compiler/rustc_span/src/edit_distance.rs
pub fn edit_distance(a: &str, b: &str, limit: usize) -> Option<usize> {
    let mut a = &a.chars().collect::<Vec<_>>()[..];
    let mut b = &b.chars().collect::<Vec<_>>()[..];

    if a.len() < b.len() {
        std::mem::swap(&mut a, &mut b);
    }

    let min_dist = a.len() - b.len();
    // If we know the limit will be exceeded, we can return early.
    if min_dist > limit {
        return None;
    }

    // Strip common prefix.
    while !b.is_empty() && !a.is_empty() {
        let (b_first, b_rest) = b.split_last().expect("Failed to split 'b' slice");
        let (a_first, a_rest) = a.split_last().expect("Failed to split 'a' slice");

        if b_first == a_first {
            a = a_rest;
            b = b_rest;
        } else {
            break;
        }
    }

    // If either string is empty, the distance is the length of the other.
    // We know that `b` is the shorter string, so we don't need to check `a`.
    if b.is_empty() {
        return Some(min_dist);
    }

    let mut prev_prev = vec![usize::MAX; b.len() + 1];
    let mut prev = (0..=b.len()).collect::<Vec<_>>();
    let mut current = vec![0; b.len() + 1];

View on GitHub (pinned to 49f8762da5)