slint-ui/slint · info
Not empty
Error message
Not empty
What it means
Internal invariant panic from `.expect("Not empty")` on `element_text_lines.first()` in tools/lsp/preview/drop_location.rs:1235. The enclosing `if element_text_lines.is_empty()` branch guarantees the vector has at least one element, so `first()` is `Some`; the expect documents that checked precondition while building the re-inserted element text with its pre-indent.
Solutions
- Keep the `first()` access inside the branch guarded by `!element_text_lines.is_empty()`.
- If the guard cannot be proven locally, switch to `element_text_lines.first().map(...).unwrap_or_default()`.
- Prefer `if let Some(first) = element_text_lines.first()` to make the invariant explicit in code rather than in a panic message.
Example fix
// before
let mut tmp = format!("{}{}\n", drop_info.insert_info.pre_indent, element_text_lines.first().expect("Not empty"));
// after
let Some(first_line) = element_text_lines.first() else { return String::new(); };
let mut tmp = format!("{}{}\n", drop_info.insert_info.pre_indent, first_line); Defensive patterns
Strategy: type-guard
Validate before calling
if element_text_lines.is_empty() { return String::new(); } Type guard
fn first_line(lines: &[String]) -> Option<&str> { lines.first().map(String::as_str) } Try / catch
// Rust: no catch; use let-else instead of expect
let Some(first) = element_text_lines.first() else { return String::new(); }; Prevention
- Keep bounds-check and indexed access adjacent in the same block.
- Use if-let/let-else so the non-empty case is encoded in control flow, not a panic string.
- Copy the guard along with the code when reusing the snippet elsewhere.
When it happens
Trigger: Not triggerable as written — the guard `if element_text_lines.is_empty() { String::new() } else { ... }` ensures `first()` succeeds. Would only panic if the code were restructured so the `.first()` call no longer sits inside the non-empty else branch (e.g. hoisting it out or converting the if to a match on something else).
Common situations: Encountered by maintainers after refactoring the workspace-edit builder in drop_location.rs so the emptiness check and the `first()` access become separated, or by anyone copying this pattern without 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
- There is always one line
- Global was just valid
- Length was checked
- 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/b4f1b589a43e998a.
Report an issue: GitHub.
Appendix: source
Thrown at tools/lsp/preview/drop_location.rs:1235
}
pub fn create_swap_element_workspace_edit(
drop_info: &DropInformation,
element: &editor_preview::ElementRcNode,
placeholder_text: String,
format: editor_preview::ByteFormat,
) -> Option<(lsp_types::WorkspaceEdit, DropData)> {
let component_type = element.component_type();
let new_text = {
let element_text_lines = extract_text_of_element(element, &["x", "y"]);
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
}
};View on GitHub (pinned to bb937076de)