slint-ui/slint · info

Length was checked

Error message

Length was checked

What it means

Internal invariant panic from `.expect("Length was checked")` on `element_text_lines.last()` in tools/lsp/preview/drop_location.rs:1246. The preceding `if element_text_lines.len() >= 2` check guarantees `last()` returns `Some`; the expect encodes that already-verified precondition while appending the closing line and post-indent to the re-inserted element text.

Solutions

  1. Keep the `.last()` call inside the `if element_text_lines.len() >= 2` block.
  2. Use `if let Some(last) = element_text_lines.last()` combined with an explicit `element_text_lines.len() >= 2` condition if both bounds matter.
  3. Add a test with a multi-line element covering the len>=2 branch of the workspace edit builder.

Example fix

// before
if element_text_lines.len() >= 2 {
    tmp.push_str(&format!("{}{}\n{}", drop_info.insert_info.indent, element_text_lines.last().expect("Length was checked"), drop_info.insert_info.post_indent));
}
// after
if let (Some(first), Some(last)) = (element_text_lines.first(), element_text_lines.last()) {
    if first != last {
        tmp.push_str(&format!("{}{}\n{}", drop_info.insert_info.indent, last, drop_info.insert_info.post_indent));
    }
}
Defensive patterns

Strategy: type-guard

Validate before calling

debug_assert!(element_text_lines.len() >= 2, "last() only called when len >= 2");

Type guard

fn last_line(lines: &[String]) -> Option<&str> { lines.last().map(String::as_str) }

Try / catch

// Rust: no catch; use Option combinators instead of expect
if element_text_lines.len() >= 2 {
    if let Some(last) = element_text_lines.last() { /* ... */ }
}

Prevention

When it happens

Trigger: Not triggerable with the current source — `last()` is only called after the `len() >= 2` guard. Panics only if a refactor removes or moves the length check away from the `last()` call, or if the vector is mutated between the check and the access.

Common situations: Hit by maintainers refactoring the multi-line element re-insertion logic in create_drop_element_workspace_edit who separate the bounds check from the indexed access, or by developers reusing this snippet elsewhere without copying the guard.

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 slint-ui/slint@bb937076de (2026-09-16). Data as JSON: /api/errors/820dc9efb8e74d85. Report an issue: GitHub.

Appendix: source

Thrown at tools/lsp/preview/drop_location.rs:1246

        if element_text_lines.is_empty() {
            String::new()
        } else {
            let mut tmp = format!(
                "{}{}\n",
                drop_info.insert_info.pre_indent,
                element_text_lines.first().expect("Not empty")
            );

            for l in element_text_lines.iter().take(element_text_lines.len() - 1).skip(1) {
                tmp.push_str(&format!("{}{l}\n", drop_info.insert_info.indent));
            }

            if element_text_lines.len() >= 2 {
                tmp.push_str(&format!(
                    "{}{}\n{}",
                    drop_info.insert_info.indent,
                    element_text_lines.last().expect("Length was checked"),
                    drop_info.insert_info.post_indent
                ));
            }

            tmp
        }
    };

    let (path, _) = drop_info.target_element_node.path_and_offset();

    let document_cache = preview::document_cache()?;
    let doc = document_cache.get_document_by_path(&path)?;
    let source_file = doc.node.as_ref().unwrap().source_file.clone();

    let mut selection_offset = drop_info.insert_info.insertion_position.offset()
        + TextSize::new(
            new_text.chars().take_while(|c| c.is_whitespace()).map(|c| c.len_utf8()).sum::<usize>()
                as u32,

View on GitHub (pinned to bb937076de)