@@ -229,13 +229,13 @@ impl<'a> Iterator for WidgetIter<'a> {
229229 Some ( first)
230230 } ) ;
231231
232- if let Some ( item ) = widget {
233- if let WidgetInstance { widget : Widget :: PopoverButton ( p ) , .. } = item {
234- self . stack . extend ( p . popover_layout . 0 . iter ( ) ) ;
232+ if let Some ( instance ) = widget {
233+ if let Widget :: PopoverButton ( popover_button ) = & * instance . widget {
234+ self . stack . extend ( popover_button . popover_layout . 0 . iter ( ) ) ;
235235 return self . next ( ) ;
236236 }
237237
238- return Some ( item ) ;
238+ return Some ( instance ) ;
239239 }
240240
241241 match self . stack . pop ( ) {
@@ -279,13 +279,15 @@ impl<'a> Iterator for WidgetIterMut<'a> {
279279 Some ( first)
280280 } ) ;
281281
282- if let Some ( widget) = widget {
283- if let WidgetInstance { widget : Widget :: PopoverButton ( p) , .. } = widget {
284- self . stack . extend ( p. popover_layout . 0 . iter_mut ( ) ) ;
285- return self . next ( ) ;
282+ if let Some ( instance) = widget {
283+ // We have to check that we're not a popover and return first, then extract the popover with an unreachable else condition second, to satisfy the borrow checker.
284+ // After Rust's Polonius is stable, we can reverse that order of steps to avoid the redundancy and unreachable statement.
285+ if !matches ! ( * instance. widget, Widget :: PopoverButton ( _) ) {
286+ return Some ( instance) ;
286287 }
287-
288- return Some ( widget) ;
288+ let Widget :: PopoverButton ( popover_button) = & mut * instance. widget else { unreachable ! ( ) } ;
289+ self . stack . extend ( popover_button. popover_layout . 0 . iter_mut ( ) ) ;
290+ return self . next ( ) ;
289291 }
290292
291293 match self . stack . pop ( ) {
@@ -362,7 +364,7 @@ impl LayoutGroup {
362364 } ;
363365 let description = description. into ( ) ;
364366 for widget in & mut widgets {
365- let val = match & mut widget. widget {
367+ let val = match & mut * widget. widget {
366368 Widget :: CheckboxInput ( x) => & mut x. tooltip_description ,
367369 Widget :: ColorInput ( x) => & mut x. tooltip_description ,
368370 Widget :: CurveInput ( x) => & mut x. tooltip_description ,
@@ -552,7 +554,7 @@ impl Diffable for LayoutGroup {
552554pub struct WidgetInstance {
553555 #[ serde( rename = "widgetId" ) ]
554556 pub widget_id : WidgetId ,
555- pub widget : Widget ,
557+ pub widget : Box < Widget > ,
556558}
557559
558560impl PartialEq for WidgetInstance {
@@ -566,7 +568,7 @@ impl WidgetInstance {
566568 pub fn new ( widget : Widget ) -> Self {
567569 Self {
568570 widget_id : WidgetId ( generate_uuid ( ) ) ,
569- widget,
571+ widget : Box :: new ( widget ) ,
570572 }
571573 }
572574}
@@ -584,7 +586,7 @@ impl Diffable for WidgetInstance {
584586 }
585587
586588 // Special handling for PopoverButton: recursively diff nested layout if only the layout changed
587- if let ( Widget :: PopoverButton ( button1) , Widget :: PopoverButton ( button2) ) = ( & mut self . widget , & new. widget ) {
589+ if let ( Widget :: PopoverButton ( button1) , Widget :: PopoverButton ( button2) ) = ( & mut * self . widget , & * new. widget ) {
588590 // Check if only the popover layout changed (all other fields are the same)
589591 if self . widget_id == new. widget_id
590592 && button1. disabled == button2. disabled
@@ -614,7 +616,7 @@ impl Diffable for WidgetInstance {
614616 }
615617
616618 fn collect_checkbox_ids ( & self , layout_target : LayoutTarget , widget_path : & mut Vec < usize > , checkbox_map : & mut HashMap < CheckboxId , CheckboxId > ) {
617- match & self . widget {
619+ match & * self . widget {
618620 Widget :: CheckboxInput ( checkbox) => {
619621 // Compute stable ID based on position and insert mapping
620622 let checkbox_id = checkbox. for_label ;
@@ -644,7 +646,7 @@ impl Diffable for WidgetInstance {
644646 self . widget_id = compute_widget_id ( layout_target, widget_path, & self . widget ) ;
645647
646648 // 2. Replace CheckboxIds if present
647- match & mut self . widget {
649+ match & mut * self . widget {
648650 Widget :: CheckboxInput ( checkbox) => {
649651 let old_id = checkbox. for_label ;
650652 if let Some ( & new_id) = checkbox_map. get ( & old_id) {
@@ -744,7 +746,7 @@ impl DiffUpdate {
744746 // Go through each widget to convert `ActionShortcut::Action` to `ActionShortcut::Shortcut` and append the key combination to the widget tooltip
745747 let convert_tooltip = |widget_instance : & mut WidgetInstance | {
746748 // Handle all the widgets that have tooltips
747- let tooltip_shortcut = match & mut widget_instance. widget {
749+ let tooltip_shortcut = match & mut * widget_instance. widget {
748750 Widget :: BreadcrumbTrailButtons ( widget) => widget. tooltip_shortcut . as_mut ( ) ,
749751 Widget :: CheckboxInput ( widget) => widget. tooltip_shortcut . as_mut ( ) ,
750752 Widget :: ColorInput ( widget) => widget. tooltip_shortcut . as_mut ( ) ,
@@ -775,7 +777,7 @@ impl DiffUpdate {
775777 }
776778
777779 // Handle RadioInput separately because its tooltips are children of the widget
778- if let Widget :: RadioInput ( radio_input) = & mut widget_instance. widget {
780+ if let Widget :: RadioInput ( radio_input) = & mut * widget_instance. widget {
779781 for radio_entry_data in & mut radio_input. entries {
780782 // Convert `ActionShortcut::Action` to `ActionShortcut::Shortcut`
781783 if let Some ( tooltip_shortcut) = radio_entry_data. tooltip_shortcut . as_mut ( ) {
@@ -827,7 +829,7 @@ impl DiffUpdate {
827829 } ;
828830
829831 // Apply shortcut conversions to all widgets that have menu lists
830- let convert_menu_lists = |widget_instance : & mut WidgetInstance | match & mut widget_instance. widget {
832+ let convert_menu_lists = |widget_instance : & mut WidgetInstance | match & mut * widget_instance. widget {
831833 Widget :: DropdownInput ( dropdown_input) => {
832834 apply_action_shortcut_to_menu_lists ( & mut dropdown_input. entries ) ;
833835 dropdown_input. entries_hash = hash_menu_list_entry_sections ( & dropdown_input. entries ) ;
0 commit comments