slint-ui/slint · error
there should be a popup menu if we want to show it
Error message
there should be a popup menu if we want to show it
What it means
Rust generator mirror of the C++ popup-menu panic: compiling the builtin `show-popup-menu` call requires `ctx.compilation_unit.popup_menu` to hold the auto-generated popup menu item tree. A None value panics because the builtin cannot be lowered without the popup menu component registered by an earlier compiler pass.
Solutions
- Run the pass that populates `CompilationUnit::popup_menu` before code generation
- Assert earlier (at unit finalization) that any `show_popup_menu` usage implies a registered popup menu
- Return a clear compile diagnostic instead of panicking when the popup menu is missing
Example fix
// before
let popup = ctx.compilation_unit.popup_menu.as_ref().expect("there should be a popup menu if we want to show it");
// after
let popup = ctx.compilation_unit.popup_menu.as_ref().unwrap_or_else(||
panic!("show_popup_menu used but compilation_unit.popup_menu was never registered")); Defensive patterns
Strategy: validation
Validate before calling
if ctx.compilation_unit.popup_menu.is_none() {
panic!("show_popup_menu lowered but popup_menu never registered in this unit");
} Type guard
let popup_menu = match ctx.compilation_unit.popup_menu.as_ref() {
Some(p) => p,
None => panic!("cannot lower show_popup_menu: no popup menu item tree registered"),
}; Prevention
- Ensure popup-menu registration precedes rust codegen in every pipeline
- Add a pipeline-final assertion tying show_popup_menu usage to registration
- Test show-popup-menu lowering via the rust generator in CI
- Mirror the check in C++ and Rust generators to catch regressions early
When it happens
Trigger: `compile_builtin_function_call` lowers a `show_popup_menu` call in a unit where `popup_menu` was never collected — the collection pass did not run (e.g. a partial pipeline like LSP or tooling), or registration failed upstream.
Common situations: Compiler/tooling development: running codegen on units that skipped the popup-menu registration pass; refactoring how builtin functions register their supporting item trees.
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
- Expression::StructFieldAccess: Cannot find a key in an…
- ShowPopupWindow is invoked on a sub-component
- there should be a popup menu if we want to show it
- Expression::ObjectAccess: Cannot find a key in an object
- model two-way bindings only exist on sub-components
AI-assisted analysis of slint-ui/slint@3a7e700487 (2026-09-16).
Data as JSON: /api/errors/60cf22c5d5073335.
Report an issue: GitHub.
Appendix: source
Thrown at internal/compiler/generator/rust.rs:4750
)
} else {
panic!("internal error: invalid args to ClosePopupWindow {arguments:?}")
}
}
BuiltinFunction::ShowPopupMenu | BuiltinFunction::ShowPopupMenuInternal => {
let [Expression::PropertyReference(context_menu_ref), entries, position] = arguments
else {
panic!("internal error: invalid args to ShowPopupMenu {arguments:?}")
};
let context_menu = access_member(context_menu_ref, ctx);
let position = compile_expression(position, ctx);
let popup = ctx
.compilation_unit
.popup_menu
.as_ref()
.expect("there should be a popup menu if we want to show it");
let popup_id =
inner_component_id(&ctx.compilation_unit.sub_components[popup.item_tree.root]);
let window_adapter_tokens = access_window_adapter_field(ctx);
let popup_ctx = EvaluationContext::new_sub_component(
ctx.compilation_unit,
popup.item_tree.root,
RustGeneratorContext { global_access: quote!(_self.globals()) },
None,
);
let access_entries = access_member(&popup.entries, &popup_ctx).unwrap();
let access_sub_menu = access_member(&popup.sub_menu, &popup_ctx).unwrap();
let access_activated = access_member(&popup.activated, &popup_ctx).unwrap();
let access_close = access_member(&popup.close, &popup_ctx).unwrap();
let close_popup = context_menu.clone().then(|context_menu| quote!{
if let Some(current_id) = #context_menu.popup_id.take() {
sp::WindowInner::from_pub(#window_adapter_tokens.window()).close_popup(current_id);View on GitHub (pinned to 3a7e700487)