{"record":{"id":"90b0ae120b7f3ab5","repo":"iced-rs/iced","slug":"line-layout-should-be-cached","errorCode":null,"errorMessage":"Line layout should be cached","messagePattern":"Line layout should be cached","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"graphics/src/text/editor.rs","lineNumber":821,"sourceCode":"        highlighter: &mut H,\n        format_highlight: impl Fn(&H::Highlight) -> highlighter::Format<Self::Font>,\n    ) {\n        let internal = self.internal();\n        let buffer = buffer_from_editor(&internal.editor);\n\n        let scroll = buffer.scroll();\n        let mut window = (internal.bounds.height * internal.hint_factor\n            / buffer.metrics().line_height)\n            .ceil() as i32;\n\n        let last_visible_line = buffer.lines[scroll.line..]\n            .iter()\n            .enumerate()\n            .find_map(|(i, line)| {\n                let visible_lines = line\n                    .layout_opt()\n                    .as_ref()\n                    .expect(\"Line layout should be cached\")\n                    .len() as i32;\n\n                if window > visible_lines {\n                    window -= visible_lines;\n                    None\n                } else {\n                    Some(scroll.line + i)\n                }\n            })\n            .unwrap_or(buffer.lines.len().saturating_sub(1));\n\n        let current_line = highlighter.current_line();\n\n        if current_line > last_visible_line {\n            return;\n        }\n\n        let editor = self.0.take().expect(\"Editor should always be initialized\");","sourceCodeStart":803,"sourceCodeEnd":839,"githubUrl":"https://github.com/iced-rs/iced/blob/3de451447bd28217bb535632867550908e29d5d0/graphics/src/text/editor.rs#L803-L839","documentation":"cosmic-text computes line layouts lazily: a BufferLine only carries a layout after shaping ran (shape_until_scroll / shape_as_needed, invoked from Editor::update/overwrite/perform). Editor::highlight (editor.rs:821) walks the visible window line by line and asserts line.layout_opt() is Some; if any line in [scroll.line, last_visible_line] was never shaped, expect(\"Line layout should be cached\") fires.","triggerScenarios":"Calling highlight before any shaping pass ran; passing bounds to update that are smaller than what highlight later assumes, so the visible window reaches unshaped lines; scrolling deep into a huge document whose shaping was cut short (shape_until_scroll with false).","commonSituations":"Custom widgets driving editor::Editor with a hand-ordered lifecycle (highlight before update); resizing the editor between update and highlight; loading very large files where shaping has not caught up with the scroll position.","solutions":["Run the editor lifecycle in order: with_text/update (which shapes) before highlight, mirroring iced's text_editor widget","Pass identical bounds to update and the subsequent highlight so the visible window matches what was shaped","For very large buffers, ensure shaping completed past the visible region before highlighting","If it persists with stock widgets, upgrade iced: visible-window/shaping order bugs were fixed across releases"],"exampleFix":"// before - highlight before any shaping ran\nlet mut editor = Editor::with_text(text);\neditor.highlight(font, &mut highlighter, fmt);\n\n// after - shape first, then highlight\neditor.update(bounds, font, size, line_height, wrapping, alignment, hint_factor, &mut highlighter);\neditor.highlight(font, &mut highlighter, fmt);","handlingStrategy":"validation","validationCode":"// before triggering highlight, confirm the visible lines are shaped\nlet shaped = editor.buffer().lines.iter().all(|l| l.layout_opt().is_some());\nif !shaped {\n    // run the update/shaping pass first (correct bounds, font, size)\n    editor.update(bounds, font, size, line_height, wrapping, alignment, hint, &mut highlighter);\n}\neditor.highlight(font, &mut highlighter, fmt);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always order the editor lifecycle: with_text/update (shapes) before highlight","Pass the same bounds to update and highlight so the visible window matches what was shaped","For very large documents, ensure shaping completes past the visible region","Model custom text widgets on iced's text_editor widget ordering"],"tags":["rust","iced","cosmic-text","editor","shaping","layout-cache"],"backgroundTag":"lazy-value-not-computed","analyzedSha":"3de451447bd28217bb535632867550908e29d5d0","analyzedAt":"2026-08-17T10:40:26.997Z","contentChangedAt":"2026-08-17T10:40:26.997Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}