From 6be707267e733fa9d3600826a1e0981d80875f42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 29 Aug 2025 04:21:43 +0200 Subject: [PATCH] Revert "Make `Widget::diff` mutable" This reverts commit 497ebcd0c36c45d6203fc84005abb81f95cf34ee. --- core/src/element.rs | 37 +++---------------------------- core/src/widget.rs | 2 +- core/src/widget/tree.rs | 26 ++++++++++------------ examples/loupe/src/main.rs | 4 ++-- examples/toast/src/main.rs | 6 ++--- runtime/src/user_interface.rs | 2 +- widget/src/button.rs | 4 ++-- widget/src/column.rs | 4 ++-- widget/src/combo_box.rs | 2 +- widget/src/container.rs | 4 ++-- widget/src/float.rs | 4 ++-- widget/src/grid.rs | 4 ++-- widget/src/helpers.rs | 8 +++---- widget/src/keyed/column.rs | 6 ++--- widget/src/lazy.rs | 6 ++--- widget/src/lazy/component.rs | 6 ++--- widget/src/mouse_area.rs | 4 ++-- widget/src/overlay/menu.rs | 4 ++-- widget/src/pane_grid.rs | 4 ++-- widget/src/pane_grid/content.rs | 6 ++--- widget/src/pane_grid/title_bar.rs | 10 ++++----- widget/src/pin.rs | 4 ++-- widget/src/responsive.rs | 11 +++------ widget/src/row.rs | 6 ++--- widget/src/scrollable.rs | 4 ++-- widget/src/sensor.rs | 4 ++-- widget/src/stack.rs | 4 ++-- widget/src/table.rs | 4 ++-- widget/src/text_input.rs | 2 +- widget/src/themer.rs | 4 ++-- widget/src/tooltip.rs | 8 +++---- 31 files changed, 83 insertions(+), 121 deletions(-) diff --git a/core/src/element.rs b/core/src/element.rs index 349aecb6..6a71296c 100644 --- a/core/src/element.rs +++ b/core/src/element.rs @@ -9,7 +9,7 @@ use crate::{ Vector, Widget, }; -use std::borrow::{Borrow, BorrowMut}; +use std::borrow::Borrow; /// A generic [`Widget`]. /// @@ -239,37 +239,6 @@ impl<'a, Message, Theme, Renderer> } } -impl<'a, Message, Theme, Renderer> - Borrow + 'a> - for &mut Element<'a, Message, Theme, Renderer> -{ - fn borrow(&self) -> &(dyn Widget + 'a) { - self.widget.borrow() - } -} - -impl<'a, Message, Theme, Renderer> - BorrowMut + 'a> - for Element<'a, Message, Theme, Renderer> -{ - fn borrow_mut( - &mut self, - ) -> &mut (dyn Widget + 'a) { - self.widget.borrow_mut() - } -} - -impl<'a, Message, Theme, Renderer> - BorrowMut + 'a> - for &mut Element<'a, Message, Theme, Renderer> -{ - fn borrow_mut( - &mut self, - ) -> &mut (dyn Widget + 'a) { - self.widget.borrow_mut() - } -} - struct Map<'a, A, B, Theme, Renderer> { widget: Box + 'a>, mapper: Box B + 'a>, @@ -309,7 +278,7 @@ where self.widget.children() } - fn diff(&mut self, tree: &mut Tree) { + fn diff(&self, tree: &mut Tree) { self.widget.diff(tree); } @@ -452,7 +421,7 @@ where self.element.widget.children() } - fn diff(&mut self, tree: &mut Tree) { + fn diff(&self, tree: &mut Tree) { self.element.widget.diff(tree); } diff --git a/core/src/widget.rs b/core/src/widget.rs index 9316dba1..3b39ffcc 100644 --- a/core/src/widget.rs +++ b/core/src/widget.rs @@ -96,7 +96,7 @@ where } /// Reconciles the [`Widget`] with the provided [`Tree`]. - fn diff(&mut self, tree: &mut Tree) { + fn diff(&self, tree: &mut Tree) { tree.children.clear(); } diff --git a/core/src/widget/tree.rs b/core/src/widget/tree.rs index 20b55360..2600cfc6 100644 --- a/core/src/widget/tree.rs +++ b/core/src/widget/tree.rs @@ -2,7 +2,7 @@ use crate::Widget; use std::any::{self, Any}; -use std::borrow::{Borrow, BorrowMut}; +use std::borrow::Borrow; use std::fmt; /// A persistent state widget tree. @@ -56,12 +56,12 @@ impl Tree { /// [`Widget::diff`]: crate::Widget::diff pub fn diff<'a, Message, Theme, Renderer>( &mut self, - mut new: impl BorrowMut + 'a>, + new: impl Borrow + 'a>, ) where Renderer: crate::Renderer, { - if self.tag == new.borrow_mut().tag() { - new.borrow_mut().diff(self); + if self.tag == new.borrow().tag() { + new.borrow().diff(self); } else { *self = Self::new(new); } @@ -70,15 +70,13 @@ impl Tree { /// Reconciles the children of the tree with the provided list of widgets. pub fn diff_children<'a, Message, Theme, Renderer>( &mut self, - new_children: &mut [impl BorrowMut< - dyn Widget + 'a, - >], + new_children: &[impl Borrow + 'a>], ) where Renderer: crate::Renderer, { self.diff_children_custom( new_children, - |tree, widget| tree.diff(widget.borrow_mut()), + |tree, widget| tree.diff(widget.borrow()), |widget| Self::new(widget.borrow()), ); } @@ -87,8 +85,8 @@ impl Tree { /// logic both for diffing and creating new widget state. pub fn diff_children_custom( &mut self, - new_children: &mut [T], - diff: impl Fn(&mut Tree, &mut T), + new_children: &[T], + diff: impl Fn(&mut Tree, &T), new_state: impl Fn(&T) -> Self, ) { if self.children.len() > new_children.len() { @@ -96,7 +94,7 @@ impl Tree { } for (child_state, new) in - self.children.iter_mut().zip(new_children.iter_mut()) + self.children.iter_mut().zip(new_children.iter()) { diff(child_state, new); } @@ -116,8 +114,8 @@ impl Tree { /// `maybe_changed` closure. pub fn diff_children_custom_with_search( current_children: &mut Vec, - new_children: &mut [T], - diff: impl Fn(&mut Tree, &mut T), + new_children: &[T], + diff: impl Fn(&mut Tree, &T), maybe_changed: impl Fn(usize) -> bool, new_state: impl Fn(&T) -> Tree, ) { @@ -185,7 +183,7 @@ pub fn diff_children_custom_with_search( // TODO: Merge loop with extend logic (?) for (child_state, new) in - current_children.iter_mut().zip(new_children.iter_mut()) + current_children.iter_mut().zip(new_children.iter()) { diff(child_state, new); } diff --git a/examples/loupe/src/main.rs b/examples/loupe/src/main.rs index ebd7a44f..89bc82da 100644 --- a/examples/loupe/src/main.rs +++ b/examples/loupe/src/main.rs @@ -87,8 +87,8 @@ mod loupe { self.content.as_widget().children() } - fn diff(&mut self, tree: &mut widget::Tree) { - self.content.as_widget_mut().diff(tree); + fn diff(&self, tree: &mut widget::Tree) { + self.content.as_widget().diff(tree); } fn size(&self) -> Size { diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs index d1be0c09..dc8c2593 100644 --- a/examples/toast/src/main.rs +++ b/examples/toast/src/main.rs @@ -314,7 +314,7 @@ mod toast { .collect() } - fn diff(&mut self, tree: &mut Tree) { + fn diff(&self, tree: &mut Tree) { let instants = tree.state.downcast_mut::>>(); // Invalidating removed instants to None allows us to remove @@ -336,8 +336,8 @@ mod toast { } tree.diff_children( - &mut std::iter::once(&mut self.content) - .chain(self.toasts.iter_mut()) + &std::iter::once(&self.content) + .chain(self.toasts.iter()) .collect::>(), ); } diff --git a/runtime/src/user_interface.rs b/runtime/src/user_interface.rs index 6e32d10f..26c96201 100644 --- a/runtime/src/user_interface.rs +++ b/runtime/src/user_interface.rs @@ -100,7 +100,7 @@ where let mut root = root.into(); let Cache { mut state } = cache; - state.diff(root.as_widget_mut()); + state.diff(root.as_widget()); let base = root.as_widget_mut().layout( &mut state, diff --git a/widget/src/button.rs b/widget/src/button.rs index 2ae1508b..6ae8d3e5 100644 --- a/widget/src/button.rs +++ b/widget/src/button.rs @@ -223,8 +223,8 @@ where vec![Tree::new(&self.content)] } - fn diff(&mut self, tree: &mut Tree) { - tree.diff_children(std::slice::from_mut(&mut self.content)); + fn diff(&self, tree: &mut Tree) { + tree.diff_children(std::slice::from_ref(&self.content)); } fn size(&self) -> Size { diff --git a/widget/src/column.rs b/widget/src/column.rs index bcbbe49e..39507a78 100644 --- a/widget/src/column.rs +++ b/widget/src/column.rs @@ -194,8 +194,8 @@ where self.children.iter().map(Tree::new).collect() } - fn diff(&mut self, tree: &mut Tree) { - tree.diff_children(&mut self.children); + fn diff(&self, tree: &mut Tree) { + tree.diff_children(&self.children); } fn size(&self) -> Size { diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs index 86533c3a..f94705d8 100644 --- a/widget/src/combo_box.rs +++ b/widget/src/combo_box.rs @@ -509,7 +509,7 @@ where vec![widget::Tree::new(&self.text_input as &dyn Widget<_, _, _>)] } - fn diff(&mut self, _tree: &mut widget::Tree) { + fn diff(&self, _tree: &mut widget::Tree) { // do nothing so the children don't get cleared } diff --git a/widget/src/container.rs b/widget/src/container.rs index 97502b17..286c5a63 100644 --- a/widget/src/container.rs +++ b/widget/src/container.rs @@ -247,8 +247,8 @@ where self.content.as_widget().children() } - fn diff(&mut self, tree: &mut Tree) { - self.content.as_widget_mut().diff(tree); + fn diff(&self, tree: &mut Tree) { + self.content.as_widget().diff(tree); } fn size(&self) -> Size { diff --git a/widget/src/float.rs b/widget/src/float.rs index a7eaf5bb..1ff6ab10 100644 --- a/widget/src/float.rs +++ b/widget/src/float.rs @@ -103,8 +103,8 @@ where self.content.as_widget().children() } - fn diff(&mut self, tree: &mut widget::Tree) { - self.content.as_widget_mut().diff(tree); + fn diff(&self, tree: &mut widget::Tree) { + self.content.as_widget().diff(tree); } fn size(&self) -> Size { diff --git a/widget/src/grid.rs b/widget/src/grid.rs index 5bf2bf6b..25e3ebe0 100644 --- a/widget/src/grid.rs +++ b/widget/src/grid.rs @@ -158,8 +158,8 @@ where self.children.iter().map(Tree::new).collect() } - fn diff(&mut self, tree: &mut Tree) { - tree.diff_children(&mut self.children); + fn diff(&self, tree: &mut Tree) { + tree.diff_children(&self.children); } fn size(&self) -> Size { diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs index b1d29127..3b1d0bbe 100644 --- a/widget/src/helpers.rs +++ b/widget/src/helpers.rs @@ -598,8 +598,8 @@ where self.content.as_widget().children() } - fn diff(&mut self, tree: &mut Tree) { - self.content.as_widget_mut().diff(tree); + fn diff(&self, tree: &mut Tree) { + self.content.as_widget().diff(tree); } fn size(&self) -> Size { @@ -761,8 +761,8 @@ where vec![Tree::new(&self.base), Tree::new(&self.top)] } - fn diff(&mut self, tree: &mut Tree) { - tree.diff_children(&mut [&mut self.base, &mut self.top]); + fn diff(&self, tree: &mut Tree) { + tree.diff_children(&[&self.base, &self.top]); } fn size(&self) -> Size { diff --git a/widget/src/keyed/column.rs b/widget/src/keyed/column.rs index 907ae479..6ca6f485 100644 --- a/widget/src/keyed/column.rs +++ b/widget/src/keyed/column.rs @@ -222,7 +222,7 @@ where self.children.iter().map(Tree::new).collect() } - fn diff(&mut self, tree: &mut Tree) { + fn diff(&self, tree: &mut Tree) { let Tree { state, children, .. } = tree; @@ -231,8 +231,8 @@ where tree::diff_children_custom_with_search( children, - &mut self.children, - |tree, child| child.as_widget_mut().diff(tree), + &self.children, + |tree, child| child.as_widget().diff(tree), |index| { self.keys.get(index).or_else(|| self.keys.last()).copied() != Some(state.keys[index]) diff --git a/widget/src/lazy.rs b/widget/src/lazy.rs index b67ba56c..ec3c9604 100644 --- a/widget/src/lazy.rs +++ b/widget/src/lazy.rs @@ -125,7 +125,7 @@ where self.with_element(|element| vec![Tree::new(element.as_widget())]) } - fn diff(&mut self, tree: &mut Tree) { + fn diff(&self, tree: &mut Tree) { let current = tree .state .downcast_mut::>(); @@ -144,8 +144,8 @@ where current.element = Rc::new(RefCell::new(Some(element))); (*self.element.borrow_mut()) = Some(current.element.clone()); - self.with_element_mut(|element| { - tree.diff_children(std::slice::from_mut(element)); + self.with_element(|element| { + tree.diff_children(std::slice::from_ref(&element.as_widget())); }); } else { (*self.element.borrow_mut()) = Some(current.element.clone()); diff --git a/widget/src/lazy/component.rs b/widget/src/lazy/component.rs index c40be4d1..1b582dee 100644 --- a/widget/src/lazy/component.rs +++ b/widget/src/lazy/component.rs @@ -147,13 +147,13 @@ where Renderer: renderer::Renderer, { fn diff_self(&self) { - self.with_element_mut(|element| { + self.with_element(|element| { self.tree .borrow_mut() .borrow_mut() .as_mut() .unwrap() - .diff_children(std::slice::from_mut(element)); + .diff_children(std::slice::from_ref(&element)); }); } @@ -279,7 +279,7 @@ where vec![] } - fn diff(&mut self, tree: &mut Tree) { + fn diff(&self, tree: &mut Tree) { let tree = tree.state.downcast_ref::>>>(); *self.tree.borrow_mut() = tree.clone(); self.rebuild_element_if_necessary(); diff --git a/widget/src/mouse_area.rs b/widget/src/mouse_area.rs index e7ce47b5..f4a76d3b 100644 --- a/widget/src/mouse_area.rs +++ b/widget/src/mouse_area.rs @@ -181,8 +181,8 @@ where vec![Tree::new(&self.content)] } - fn diff(&mut self, tree: &mut Tree) { - tree.diff_children(std::slice::from_mut(&mut self.content)); + fn diff(&self, tree: &mut Tree) { + tree.diff_children(std::slice::from_ref(&self.content)); } fn size(&self) -> Size { diff --git a/widget/src/overlay/menu.rs b/widget/src/overlay/menu.rs index e84ae858..c4c5b521 100644 --- a/widget/src/overlay/menu.rs +++ b/widget/src/overlay/menu.rs @@ -205,7 +205,7 @@ where class, } = menu; - let mut list = Scrollable::new(List { + let list = Scrollable::new(List { options, hovered_option, on_selected, @@ -218,7 +218,7 @@ where class, }); - state.tree.diff(&mut list as &mut dyn Widget<_, _, _>); + state.tree.diff(&list as &dyn Widget<_, _, _>); Self { position, diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs index 3dd0c941..8c63fe63 100644 --- a/widget/src/pane_grid.rs +++ b/widget/src/pane_grid.rs @@ -378,7 +378,7 @@ where self.contents.iter().map(Content::state).collect() } - fn diff(&mut self, tree: &mut Tree) { + fn diff(&self, tree: &mut Tree) { let Memory { order, .. } = tree.state.downcast_ref(); // `Pane` always increments and is iterated by Ord so new @@ -401,7 +401,7 @@ where }); tree.diff_children_custom( - &mut self.contents, + &self.contents, |state, content| content.diff(state), Content::state, ); diff --git a/widget/src/pane_grid/content.rs b/widget/src/pane_grid/content.rs index 00f0d060..6592694b 100644 --- a/widget/src/pane_grid/content.rs +++ b/widget/src/pane_grid/content.rs @@ -91,13 +91,13 @@ where } } - pub(super) fn diff(&mut self, tree: &mut Tree) { + pub(super) fn diff(&self, tree: &mut Tree) { if tree.children.len() == 2 { - if let Some(title_bar) = self.title_bar.as_mut() { + if let Some(title_bar) = self.title_bar.as_ref() { title_bar.diff(&mut tree.children[1]); } - tree.children[0].diff(&mut self.body); + tree.children[0].diff(&self.body); } else { *tree = self.state(); } diff --git a/widget/src/pane_grid/title_bar.rs b/widget/src/pane_grid/title_bar.rs index 598cbcf5..7d15bf80 100644 --- a/widget/src/pane_grid/title_bar.rs +++ b/widget/src/pane_grid/title_bar.rs @@ -128,17 +128,17 @@ where } } - pub(super) fn diff(&mut self, tree: &mut Tree) { + pub(super) fn diff(&self, tree: &mut Tree) { if tree.children.len() == 3 { - if let Some(controls) = self.controls.as_mut() { - if let Some(compact) = controls.compact.as_mut() { + if let Some(controls) = self.controls.as_ref() { + if let Some(compact) = controls.compact.as_ref() { tree.children[2].diff(compact); } - tree.children[1].diff(&mut controls.full); + tree.children[1].diff(&controls.full); } - tree.children[0].diff(&mut self.content); + tree.children[0].diff(&self.content); } else { *tree = self.state(); } diff --git a/widget/src/pin.rs b/widget/src/pin.rs index f4a1c667..04ed0324 100644 --- a/widget/src/pin.rs +++ b/widget/src/pin.rs @@ -127,8 +127,8 @@ where self.content.as_widget().children() } - fn diff(&mut self, tree: &mut widget::Tree) { - self.content.as_widget_mut().diff(tree); + fn diff(&self, tree: &mut widget::Tree) { + self.content.as_widget().diff(tree); } fn size(&self) -> Size { diff --git a/widget/src/responsive.rs b/widget/src/responsive.rs index 6bb86a12..a987a430 100644 --- a/widget/src/responsive.rs +++ b/widget/src/responsive.rs @@ -3,7 +3,7 @@ use crate::core::mouse; use crate::core::overlay; use crate::core::renderer; use crate::core::widget; -use crate::core::widget::tree::{self, Tree}; +use crate::core::widget::Tree; use crate::core::{ self, Clipboard, Element, Event, Length, Rectangle, Shell, Size, Vector, Widget, @@ -66,12 +66,7 @@ impl Widget where Renderer: core::Renderer, { - fn tag(&self) -> tree::Tag { - struct Marker; - tree::Tag::of::() - } - - fn diff(&mut self, _tree: &mut Tree) { + fn diff(&self, _tree: &mut Tree) { // Diff is deferred to layout } @@ -92,7 +87,7 @@ where let size = limits.max(); self.content = (self.view)(size); - tree.diff_children(std::slice::from_mut(&mut self.content)); + tree.diff_children(std::slice::from_ref(&self.content)); let node = self.content.as_widget_mut().layout( &mut tree.children[0], diff --git a/widget/src/row.rs b/widget/src/row.rs index 6667438b..af1f490c 100644 --- a/widget/src/row.rs +++ b/widget/src/row.rs @@ -196,8 +196,8 @@ where self.children.iter().map(Tree::new).collect() } - fn diff(&mut self, tree: &mut Tree) { - tree.diff_children(&mut self.children); + fn diff(&self, tree: &mut Tree) { + tree.diff_children(&self.children); } fn size(&self) -> Size { @@ -398,7 +398,7 @@ where self.row.children() } - fn diff(&mut self, tree: &mut Tree) { + fn diff(&self, tree: &mut Tree) { self.row.diff(tree); } diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index 9c4748ea..c70c3cf2 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -399,8 +399,8 @@ where vec![Tree::new(&self.content)] } - fn diff(&mut self, tree: &mut Tree) { - tree.diff_children(std::slice::from_mut(&mut self.content)); + fn diff(&self, tree: &mut Tree) { + tree.diff_children(std::slice::from_ref(&self.content)); } fn size(&self) -> Size { diff --git a/widget/src/sensor.rs b/widget/src/sensor.rs index fd7a3510..e0122b2e 100644 --- a/widget/src/sensor.rs +++ b/widget/src/sensor.rs @@ -184,8 +184,8 @@ where vec![Tree::new(&self.content)] } - fn diff(&mut self, tree: &mut Tree) { - tree.diff_children(std::slice::from_mut(&mut self.content)); + fn diff(&self, tree: &mut Tree) { + tree.diff_children(&[&self.content]); } fn update( diff --git a/widget/src/stack.rs b/widget/src/stack.rs index 63a6b97e..c0fb3147 100644 --- a/widget/src/stack.rs +++ b/widget/src/stack.rs @@ -146,8 +146,8 @@ where self.children.iter().map(Tree::new).collect() } - fn diff(&mut self, tree: &mut Tree) { - tree.diff_children(&mut self.children); + fn diff(&self, tree: &mut Tree) { + tree.diff_children(&self.children); } fn size(&self) -> Size { diff --git a/widget/src/table.rs b/widget/src/table.rs index 97083835..06b47124 100644 --- a/widget/src/table.rs +++ b/widget/src/table.rs @@ -227,8 +227,8 @@ where .collect() } - fn diff(&mut self, state: &mut widget::Tree) { - state.diff_children(&mut self.cells); + fn diff(&self, state: &mut widget::Tree) { + state.diff_children(&self.cells); } fn layout( diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index 1a4f8a99..c385b34b 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -654,7 +654,7 @@ where tree::State::new(State::::new()) } - fn diff(&mut self, tree: &mut Tree) { + fn diff(&self, tree: &mut Tree) { let state = tree.state.downcast_mut::>(); // Stop pasting if input becomes disabled diff --git a/widget/src/themer.rs b/widget/src/themer.rs index a089d1d5..f335cd01 100644 --- a/widget/src/themer.rs +++ b/widget/src/themer.rs @@ -81,8 +81,8 @@ where self.content.as_widget().children() } - fn diff(&mut self, tree: &mut Tree) { - self.content.as_widget_mut().diff(tree); + fn diff(&self, tree: &mut Tree) { + self.content.as_widget().diff(tree); } fn size(&self) -> Size { diff --git a/widget/src/tooltip.rs b/widget/src/tooltip.rs index 782258da..4c2c1a2e 100644 --- a/widget/src/tooltip.rs +++ b/widget/src/tooltip.rs @@ -155,10 +155,10 @@ where ] } - fn diff(&mut self, tree: &mut widget::Tree) { - tree.diff_children(&mut [ - self.content.as_widget_mut(), - self.tooltip.as_widget_mut(), + fn diff(&self, tree: &mut widget::Tree) { + tree.diff_children(&[ + self.content.as_widget(), + self.tooltip.as_widget(), ]); }