diff --git a/editor/src/dispatcher.rs b/editor/src/dispatcher.rs index 66e82e322..cfffefefe 100644 --- a/editor/src/dispatcher.rs +++ b/editor/src/dispatcher.rs @@ -594,7 +594,7 @@ mod test { if let FrontendMessage::UpdateDialogColumn1 { diff } = response { if let DiffUpdate::Layout(sub_layout) = &diff[0].new_value { if let LayoutGroup::Row { widgets } = &sub_layout.0[0] { - if let Widget::TextLabel(TextLabel { value, .. }) = &widgets[0].widget { + if let Widget::TextLabel(TextLabel { value, .. }) = &*widgets[0].widget { print_problem_to_terminal_on_failure(value); } } diff --git a/editor/src/messages/layout/layout_message_handler.rs b/editor/src/messages/layout/layout_message_handler.rs index 2f34cbd9b..dcfcc1da8 100644 --- a/editor/src/messages/layout/layout_message_handler.rs +++ b/editor/src/messages/layout/layout_message_handler.rs @@ -71,7 +71,7 @@ impl LayoutMessageHandler { return Some((widget, widget_path)); } - if let Widget::PopoverButton(popover) = &widget.widget { + if let Widget::PopoverButton(popover) = &*widget.widget { stack.extend( popover .popover_layout @@ -97,7 +97,7 @@ impl LayoutMessageHandler { return Some((cell, widget_path)); } - if let Widget::PopoverButton(popover) = &cell.widget { + if let Widget::PopoverButton(popover) = &*cell.widget { stack.extend( popover .popover_layout @@ -126,7 +126,7 @@ impl LayoutMessageHandler { return; }; - match &mut widget_instance.widget { + match &mut *widget_instance.widget { Widget::BreadcrumbTrailButtons(breadcrumb_trail_buttons) => { let callback_message = match action { WidgetValueAction::Commit => (breadcrumb_trail_buttons.on_commit.callback)(&()), diff --git a/editor/src/messages/layout/utility_types/layout_widget.rs b/editor/src/messages/layout/utility_types/layout_widget.rs index 6224ea4f0..dedb17c1c 100644 --- a/editor/src/messages/layout/utility_types/layout_widget.rs +++ b/editor/src/messages/layout/utility_types/layout_widget.rs @@ -229,13 +229,13 @@ impl<'a> Iterator for WidgetIter<'a> { Some(first) }); - if let Some(item) = widget { - if let WidgetInstance { widget: Widget::PopoverButton(p), .. } = item { - self.stack.extend(p.popover_layout.0.iter()); + if let Some(instance) = widget { + if let Widget::PopoverButton(popover_button) = &*instance.widget { + self.stack.extend(popover_button.popover_layout.0.iter()); return self.next(); } - return Some(item); + return Some(instance); } match self.stack.pop() { @@ -279,13 +279,15 @@ impl<'a> Iterator for WidgetIterMut<'a> { Some(first) }); - if let Some(widget) = widget { - if let WidgetInstance { widget: Widget::PopoverButton(p), .. } = widget { - self.stack.extend(p.popover_layout.0.iter_mut()); - return self.next(); + if let Some(instance) = widget { + // 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. + // After Rust's Polonius is stable, we can reverse that order of steps to avoid the redundancy and unreachable statement. + if !matches!(*instance.widget, Widget::PopoverButton(_)) { + return Some(instance); } - - return Some(widget); + let Widget::PopoverButton(popover_button) = &mut *instance.widget else { unreachable!() }; + self.stack.extend(popover_button.popover_layout.0.iter_mut()); + return self.next(); } match self.stack.pop() { @@ -362,7 +364,7 @@ impl LayoutGroup { }; let description = description.into(); for widget in &mut widgets { - let val = match &mut widget.widget { + let val = match &mut *widget.widget { Widget::CheckboxInput(x) => &mut x.tooltip_description, Widget::ColorInput(x) => &mut x.tooltip_description, Widget::CurveInput(x) => &mut x.tooltip_description, @@ -552,7 +554,7 @@ impl Diffable for LayoutGroup { pub struct WidgetInstance { #[serde(rename = "widgetId")] pub widget_id: WidgetId, - pub widget: Widget, + pub widget: Box, } impl PartialEq for WidgetInstance { @@ -566,7 +568,7 @@ impl WidgetInstance { pub fn new(widget: Widget) -> Self { Self { widget_id: WidgetId(generate_uuid()), - widget, + widget: Box::new(widget), } } } @@ -584,7 +586,7 @@ impl Diffable for WidgetInstance { } // Special handling for PopoverButton: recursively diff nested layout if only the layout changed - if let (Widget::PopoverButton(button1), Widget::PopoverButton(button2)) = (&mut self.widget, &new.widget) { + if let (Widget::PopoverButton(button1), Widget::PopoverButton(button2)) = (&mut *self.widget, &*new.widget) { // Check if only the popover layout changed (all other fields are the same) if self.widget_id == new.widget_id && button1.disabled == button2.disabled @@ -614,7 +616,7 @@ impl Diffable for WidgetInstance { } fn collect_checkbox_ids(&self, layout_target: LayoutTarget, widget_path: &mut Vec, checkbox_map: &mut HashMap) { - match &self.widget { + match &*self.widget { Widget::CheckboxInput(checkbox) => { // Compute stable ID based on position and insert mapping let checkbox_id = checkbox.for_label; @@ -644,7 +646,7 @@ impl Diffable for WidgetInstance { self.widget_id = compute_widget_id(layout_target, widget_path, &self.widget); // 2. Replace CheckboxIds if present - match &mut self.widget { + match &mut *self.widget { Widget::CheckboxInput(checkbox) => { let old_id = checkbox.for_label; if let Some(&new_id) = checkbox_map.get(&old_id) { @@ -744,7 +746,7 @@ impl DiffUpdate { // Go through each widget to convert `ActionShortcut::Action` to `ActionShortcut::Shortcut` and append the key combination to the widget tooltip let convert_tooltip = |widget_instance: &mut WidgetInstance| { // Handle all the widgets that have tooltips - let tooltip_shortcut = match &mut widget_instance.widget { + let tooltip_shortcut = match &mut *widget_instance.widget { Widget::BreadcrumbTrailButtons(widget) => widget.tooltip_shortcut.as_mut(), Widget::CheckboxInput(widget) => widget.tooltip_shortcut.as_mut(), Widget::ColorInput(widget) => widget.tooltip_shortcut.as_mut(), @@ -775,7 +777,7 @@ impl DiffUpdate { } // Handle RadioInput separately because its tooltips are children of the widget - if let Widget::RadioInput(radio_input) = &mut widget_instance.widget { + if let Widget::RadioInput(radio_input) = &mut *widget_instance.widget { for radio_entry_data in &mut radio_input.entries { // Convert `ActionShortcut::Action` to `ActionShortcut::Shortcut` if let Some(tooltip_shortcut) = radio_entry_data.tooltip_shortcut.as_mut() { @@ -827,7 +829,7 @@ impl DiffUpdate { }; // Apply shortcut conversions to all widgets that have menu lists - let convert_menu_lists = |widget_instance: &mut WidgetInstance| match &mut widget_instance.widget { + let convert_menu_lists = |widget_instance: &mut WidgetInstance| match &mut *widget_instance.widget { Widget::DropdownInput(dropdown_input) => { apply_action_shortcut_to_menu_lists(&mut dropdown_input.entries); dropdown_input.entries_hash = hash_menu_list_entry_sections(&dropdown_input.entries);