Skip to content

Commit 9d26c04

Browse files
authored
Box the widget: Widget field of WidgetInstance (#3506)
Box the `pub widget: Box<Widget>` field of `WidgetInstance`
1 parent 20bbe6c commit 9d26c04

File tree

3 files changed

+25
-23
lines changed

3 files changed

+25
-23
lines changed

editor/src/dispatcher.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ mod test {
594594
if let FrontendMessage::UpdateDialogColumn1 { diff } = response {
595595
if let DiffUpdate::Layout(sub_layout) = &diff[0].new_value {
596596
if let LayoutGroup::Row { widgets } = &sub_layout.0[0] {
597-
if let Widget::TextLabel(TextLabel { value, .. }) = &widgets[0].widget {
597+
if let Widget::TextLabel(TextLabel { value, .. }) = &*widgets[0].widget {
598598
print_problem_to_terminal_on_failure(value);
599599
}
600600
}

editor/src/messages/layout/layout_message_handler.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ impl LayoutMessageHandler {
7171
return Some((widget, widget_path));
7272
}
7373

74-
if let Widget::PopoverButton(popover) = &widget.widget {
74+
if let Widget::PopoverButton(popover) = &*widget.widget {
7575
stack.extend(
7676
popover
7777
.popover_layout
@@ -97,7 +97,7 @@ impl LayoutMessageHandler {
9797
return Some((cell, widget_path));
9898
}
9999

100-
if let Widget::PopoverButton(popover) = &cell.widget {
100+
if let Widget::PopoverButton(popover) = &*cell.widget {
101101
stack.extend(
102102
popover
103103
.popover_layout
@@ -126,7 +126,7 @@ impl LayoutMessageHandler {
126126
return;
127127
};
128128

129-
match &mut widget_instance.widget {
129+
match &mut *widget_instance.widget {
130130
Widget::BreadcrumbTrailButtons(breadcrumb_trail_buttons) => {
131131
let callback_message = match action {
132132
WidgetValueAction::Commit => (breadcrumb_trail_buttons.on_commit.callback)(&()),

editor/src/messages/layout/utility_types/layout_widget.rs

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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 {
552554
pub struct WidgetInstance {
553555
#[serde(rename = "widgetId")]
554556
pub widget_id: WidgetId,
555-
pub widget: Widget,
557+
pub widget: Box<Widget>,
556558
}
557559

558560
impl 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

Comments
 (0)