{"record":{"id":"ff19549bc5e0bfeb","repo":"gleam-lang/gleam","slug":"failed-to-split-b-slice","errorCode":null,"errorMessage":"Failed to split 'b' slice","messagePattern":"Failed to split 'b' slice","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler-core/src/error.rs","lineNumber":829,"sourceCode":"\n// https://github.com/rust-lang/rust/blob/03994e498df79aa1f97f7bbcfd52d57c8e865049/compiler/rustc_span/src/edit_distance.rs\npub fn edit_distance(a: &str, b: &str, limit: usize) -> Option<usize> {\n    let mut a = &a.chars().collect::<Vec<_>>()[..];\n    let mut b = &b.chars().collect::<Vec<_>>()[..];\n\n    if a.len() < b.len() {\n        std::mem::swap(&mut a, &mut b);\n    }\n\n    let min_dist = a.len() - b.len();\n    // If we know the limit will be exceeded, we can return early.\n    if min_dist > limit {\n        return None;\n    }\n\n    // Strip common prefix.\n    while !b.is_empty() && !a.is_empty() {\n        let (b_first, b_rest) = b.split_last().expect(\"Failed to split 'b' slice\");\n        let (a_first, a_rest) = a.split_last().expect(\"Failed to split 'a' slice\");\n\n        if b_first == a_first {\n            a = a_rest;\n            b = b_rest;\n        } else {\n            break;\n        }\n    }\n\n    // If either string is empty, the distance is the length of the other.\n    // We know that `b` is the shorter string, so we don't need to check `a`.\n    if b.is_empty() {\n        return Some(min_dist);\n    }\n\n    let mut prev_prev = vec![usize::MAX; b.len() + 1];\n    let mut prev = (0..=b.len()).collect::<Vec<_>>();","sourceCodeStart":811,"sourceCodeEnd":847,"githubUrl":"https://github.com/gleam-lang/gleam/blob/49f8762da595eb3c8f576656a4200a142ca188c9/compiler-core/src/error.rs#L811-L847","documentation":"This `expect` guards `b.split_last()` inside the Levenshtein-style `did_you_mean` similarity helper in `compiler-core/src/error.rs`. The loop precondition `!b.is_empty() && !a.is_empty()` should guarantee both slices are non-empty, so `split_last` can only fail if the slices were mutated concurrently or the invariant is broken elsewhere — making this an internal defensive assertion, not an expected user-facing error.","triggerScenarios":"Panics only if `split_last` is called on an empty slice despite the while-loop guard, i.e. a logic bug upstream in how `a`/`b` are computed or sliced, or unsafe concurrent mutation of the slices between the emptiness check and the split.","commonSituations":"Effectively never hit by library users; it would appear as a compiler panic (ICE) while generating a 'did you mean' suggestion for a mistyped identifier, only in the presence of a compiler bug or data race.","solutions":["File a compiler bug with the input that triggered suggestion generation if this panic is ever observed","Upgrade Gleam to a version where the suggestion helper has been audited","As a library change, replace `expect` with a `match` that returns `None` on empty slices so the helper degrades gracefully instead of panicking"],"exampleFix":"// before\nlet (b_first, b_rest) = b.split_last().expect(\"Failed to split 'b' slice\");\n// after\nlet Some((b_first, b_rest)) = b.split_last() else { return None; };\nlet Some((a_first, a_rest)) = a.split_last() else { return None; };","handlingStrategy":"fallback","validationCode":"// Not user-triggerable; if embedding the crate, verify inputs to did_you_mean are non-empty:\nassert!(!a.is_empty() && !b.is_empty(), \"did_you_mean requires non-empty slices\");","typeGuard":null,"tryCatchPattern":"// no user-side catch exists for an ICE; isolate compiler runs:\nlet out = std::process::Command::new(\"gleam\").arg(\"build\").output();\nif let Err(e) = out { eprintln!(\"compiler crashed: {e}\"); }","preventionTips":["Treat any occurrence as a compiler bug — file it with the exact input","Stay on a recent Gleam release where suggestion helpers are tested","When modifying this code, use `let Some(...) else { return None }` instead of expect"],"tags":["rust","compiler","levenshtein","invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"49f8762da595eb3c8f576656a4200a142ca188c9","analyzedAt":"2026-09-14T11:14:59.388Z","contentChangedAt":"2026-09-14T11:14:59.388Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}