From 4c88e6de88647842d20bf1f05ddaa9b16b0f55da Mon Sep 17 00:00:00 2001 From: DasLixou Date: Sat, 16 Nov 2024 18:49:48 +0100 Subject: [PATCH 1/2] Ref with lifetime-limited values and simpler any_compose --- crates/actuate-core/src/lib.rs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/crates/actuate-core/src/lib.rs b/crates/actuate-core/src/lib.rs index c6409a3..8a0dbad 100644 --- a/crates/actuate-core/src/lib.rs +++ b/crates/actuate-core/src/lib.rs @@ -455,19 +455,21 @@ impl<'a, C> Deref for Scope<'a, C> { /// Use an immutable reference to a value of type `T`. /// /// `make_value` will only be called once to initialize this value. -pub fn use_ref(cx: &ScopeState, make_value: impl FnOnce() -> T) -> &T { +pub fn use_ref<'a, T: 'a>(cx: &'a ScopeState, make_value: impl FnOnce() -> T) -> &'a T { let hooks = unsafe { &mut *cx.hooks.get() }; let idx = cx.hook_idx.get(); cx.hook_idx.set(idx + 1); let any = if idx >= hooks.len() { - hooks.push(Box::new(make_value())); + let b = Box::new(make_value()); + hooks.push(unsafe { core::mem::transmute::, Box<()>>(b) }); hooks.last().unwrap() } else { hooks.get(idx).unwrap() }; - (**any).downcast_ref().unwrap() + let b = (**any).downcast_ref::<()>().unwrap(); + unsafe { core::mem::transmute::<&(), &T>(b) } } struct MutState { @@ -967,7 +969,7 @@ where let cx = Scope { me: self, state }; - let cell: &UnsafeCell>> = use_ref(&cx, || UnsafeCell::new(None)); + let cell: &UnsafeCell> = use_ref(&cx, || UnsafeCell::new(None)); let cell = unsafe { &mut *cell.get() }; let child_state = use_ref(&cx, ScopeState::default); @@ -992,14 +994,7 @@ where *child_state.contexts.borrow_mut() = cx.contexts.borrow().clone(); child_state.is_parent_changed.set(true); - unsafe { - if let Some(ref mut content) = cell { - child.reborrow((**content).as_ptr_mut()); - } else { - let boxed: Box = Box::new(child); - *cell = Some(mem::transmute(boxed)); - } - } + *cell = Some(child); } else { child_state.is_parent_changed.set(false); } From a2a2c11f9fd97a8fc6b7eeb535b56e36980e253e Mon Sep 17 00:00:00 2001 From: DasLixou Date: Sat, 16 Nov 2024 19:14:35 +0100 Subject: [PATCH 2/2] Also for mut? --- crates/actuate-core/src/lib.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/crates/actuate-core/src/lib.rs b/crates/actuate-core/src/lib.rs index 8a0dbad..e20cc71 100644 --- a/crates/actuate-core/src/lib.rs +++ b/crates/actuate-core/src/lib.rs @@ -472,15 +472,15 @@ pub fn use_ref<'a, T: 'a>(cx: &'a ScopeState, make_value: impl FnOnce() -> T) -> unsafe { core::mem::transmute::<&(), &T>(b) } } -struct MutState { - value: T, +struct MutState { generation: Cell, + value: T, } /// Use a mutable reference to a value of type `T`. /// /// `make_value` will only be called once to initialize this value. -pub fn use_mut(cx: &ScopeState, make_value: impl FnOnce() -> T) -> Mut { +pub fn use_mut<'a, T: 'a>(cx: &'a ScopeState, make_value: impl FnOnce() -> T) -> Mut<'a, T> { let hooks = unsafe { &mut *cx.hooks.get() }; let idx = cx.hook_idx.get(); @@ -491,12 +491,14 @@ pub fn use_mut(cx: &ScopeState, make_value: impl FnOnce() -> T) -> M value: make_value(), generation: Cell::new(0), }; - hooks.push(Box::new(state)); + let b = Box::new(state); + hooks.push(unsafe { core::mem::transmute::<_, Box>>(b) }); hooks.last_mut().unwrap() } else { hooks.get_mut(idx).unwrap() }; - let state: &mut MutState = any.downcast_mut().unwrap(); + let state: &mut MutState<()> = any.downcast_mut().unwrap(); + let state = unsafe { core::mem::transmute::<_, &mut MutState>(state) }; Mut { ptr: &mut state.value as *mut T,