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
- Keep the `.last()` call inside the `if element_text_lines.len() >= 2` block.
- Use `if let Some(last) = element_text_lines.last()` combined with an explicit `element_text_lines.len() >= 2` condition if both bounds matter.
- 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
- Never mutate the vec between the len check and last().
- Use debug_assert! to document preconditions without release panics.
- Add a multi-line element test covering the len>=2 branch.
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
- Global was just valid
- Not empty
- There is always one line
- an identifier
- EditorSession must have at least one preview
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)