From 4bc2f4a7131659d92e478b6ec5c832f661d2fac5 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Fri, 8 Mar 2024 10:46:34 -0600 Subject: [PATCH] add more docs around lifetime downcasting --- packages/generational-box/src/lib.rs | 12 ++++++++---- packages/generational-box/src/sync.rs | 8 ++++++-- packages/generational-box/src/unsync.rs | 8 ++++++-- packages/router/examples/simple_routes.rs | 2 +- packages/signals/examples/errors.rs | 8 ++++---- packages/signals/src/copy_value.rs | 6 ++++-- packages/signals/src/global/signal.rs | 4 +++- packages/signals/src/read.rs | 5 +++-- packages/signals/src/signal.rs | 8 ++++++-- packages/signals/src/write.rs | 8 +++++--- 10 files changed, 46 insertions(+), 23 deletions(-) diff --git a/packages/generational-box/src/lib.rs b/packages/generational-box/src/lib.rs index f933514d5..95e5ef056 100644 --- a/packages/generational-box/src/lib.rs +++ b/packages/generational-box/src/lib.rs @@ -234,13 +234,17 @@ pub trait AnyStorage: Default { /// Downcast a reference in a Ref to a more specific lifetime /// - /// This function enforces the variance of the lifetime parameter `'a` in Ref. - fn downcast_ref<'a: 'b, 'b, T: ?Sized + 'static>(ref_: Self::Ref<'a, T>) -> Self::Ref<'b, T>; + /// This function enforces the variance of the lifetime parameter `'a` in Ref. Rust will typically infer this cast with a concrete type, but it cannot with a generic type. + fn downcast_lifetime_ref<'a: 'b, 'b, T: ?Sized + 'static>( + ref_: Self::Ref<'a, T>, + ) -> Self::Ref<'b, T>; /// Downcast a mutable reference in a RefMut to a more specific lifetime /// - /// This function enforces the variance of the lifetime parameter `'a` in Ref. - fn downcast_mut<'a: 'b, 'b, T: ?Sized + 'static>(mut_: Self::Mut<'a, T>) -> Self::Mut<'b, T>; + /// This function enforces the variance of the lifetime parameter `'a` in Mut. Rust will typically infer this cast with a concrete type, but it cannot with a generic type. + fn downcast_lifetime_mut<'a: 'b, 'b, T: ?Sized + 'static>( + mut_: Self::Mut<'a, T>, + ) -> Self::Mut<'b, T>; /// Try to map the mutable ref. fn try_map_mut( diff --git a/packages/generational-box/src/sync.rs b/packages/generational-box/src/sync.rs index 74643f40e..28730d7af 100644 --- a/packages/generational-box/src/sync.rs +++ b/packages/generational-box/src/sync.rs @@ -23,11 +23,15 @@ impl AnyStorage for SyncStorage { type Ref<'a, R: ?Sized + 'static> = GenerationalRef>; type Mut<'a, W: ?Sized + 'static> = GenerationalRefMut>; - fn downcast_ref<'a: 'b, 'b, T: ?Sized + 'static>(ref_: Self::Ref<'a, T>) -> Self::Ref<'b, T> { + fn downcast_lifetime_ref<'a: 'b, 'b, T: ?Sized + 'static>( + ref_: Self::Ref<'a, T>, + ) -> Self::Ref<'b, T> { ref_ } - fn downcast_mut<'a: 'b, 'b, T: ?Sized + 'static>(mut_: Self::Mut<'a, T>) -> Self::Mut<'b, T> { + fn downcast_lifetime_mut<'a: 'b, 'b, T: ?Sized + 'static>( + mut_: Self::Mut<'a, T>, + ) -> Self::Mut<'b, T> { mut_ } diff --git a/packages/generational-box/src/unsync.rs b/packages/generational-box/src/unsync.rs index 753940b82..ed0f791f3 100644 --- a/packages/generational-box/src/unsync.rs +++ b/packages/generational-box/src/unsync.rs @@ -92,11 +92,15 @@ impl AnyStorage for UnsyncStorage { type Ref<'a, R: ?Sized + 'static> = GenerationalRef>; type Mut<'a, W: ?Sized + 'static> = GenerationalRefMut>; - fn downcast_ref<'a: 'b, 'b, T: ?Sized + 'static>(ref_: Self::Ref<'a, T>) -> Self::Ref<'b, T> { + fn downcast_lifetime_ref<'a: 'b, 'b, T: ?Sized + 'static>( + ref_: Self::Ref<'a, T>, + ) -> Self::Ref<'b, T> { ref_ } - fn downcast_mut<'a: 'b, 'b, T: ?Sized + 'static>(mut_: Self::Mut<'a, T>) -> Self::Mut<'b, T> { + fn downcast_lifetime_mut<'a: 'b, 'b, T: ?Sized + 'static>( + mut_: Self::Mut<'a, T>, + ) -> Self::Mut<'b, T> { mut_ } diff --git a/packages/router/examples/simple_routes.rs b/packages/router/examples/simple_routes.rs index 64ac0c2ff..904b7d8e0 100644 --- a/packages/router/examples/simple_routes.rs +++ b/packages/router/examples/simple_routes.rs @@ -123,7 +123,7 @@ fn Route3(dynamic: String) -> Element { oninput: move |evt| { *current_route_str.write() = evt.value(); }, - value: "{current_route_str.read()}" + value: "{current_route_str}" } "dynamic: {dynamic}" Link { to: Route::Route2 { user_id: 8888 }, "hello world link" } diff --git a/packages/signals/examples/errors.rs b/packages/signals/examples/errors.rs index 31b89f43a..9f1797c9d 100644 --- a/packages/signals/examples/errors.rs +++ b/packages/signals/examples/errors.rs @@ -30,9 +30,9 @@ fn app() -> Element { #[component] fn Read() -> Element { - let mut signal = use_signal_sync(|| 0); + let signal = use_signal_sync(|| 0); - let _write = signal.write(); + let _write = signal.write_unchecked(); let _read = signal.read(); unreachable!() @@ -40,10 +40,10 @@ fn Read() -> Element { #[component] fn ReadMut() -> Element { - let mut signal = use_signal_sync(|| 0); + let signal = use_signal_sync(|| 0); let _read = signal.read(); - let _write = signal.write(); + let _write = signal.write_unchecked(); unreachable!() } diff --git a/packages/signals/src/copy_value.rs b/packages/signals/src/copy_value.rs index 5dbf41a3c..97ee1ffbc 100644 --- a/packages/signals/src/copy_value.rs +++ b/packages/signals/src/copy_value.rs @@ -238,8 +238,10 @@ impl> Writable for CopyValue { S::try_map_mut(mut_, f) } - fn downcast_mut<'a: 'b, 'b, R: ?Sized + 'static>(mut_: Self::Mut<'a, R>) -> Self::Mut<'b, R> { - S::downcast_mut(mut_) + fn downcast_lifetime_mut<'a: 'b, 'b, R: ?Sized + 'static>( + mut_: Self::Mut<'a, R>, + ) -> Self::Mut<'b, R> { + S::downcast_lifetime_mut(mut_) } #[track_caller] diff --git a/packages/signals/src/global/signal.rs b/packages/signals/src/global/signal.rs index f292f7444..7bdab6e0b 100644 --- a/packages/signals/src/global/signal.rs +++ b/packages/signals/src/global/signal.rs @@ -104,7 +104,9 @@ impl Writable for GlobalSignal { Write::filter_map(ref_, f) } - fn downcast_mut<'a: 'b, 'b, R: ?Sized + 'static>(mut_: Self::Mut<'a, R>) -> Self::Mut<'b, R> { + fn downcast_lifetime_mut<'a: 'b, 'b, R: ?Sized + 'static>( + mut_: Self::Mut<'a, R>, + ) -> Self::Mut<'b, R> { Write::downcast_lifetime(mut_) } diff --git a/packages/signals/src/read.rs b/packages/signals/src/read.rs index 3bc953cdb..0a06ec268 100644 --- a/packages/signals/src/read.rs +++ b/packages/signals/src/read.rs @@ -53,7 +53,8 @@ pub trait Readable { /// Try to get the current value of the state. If this is a signal, this will subscribe the current scope to the signal. #[track_caller] fn try_read(&self) -> Result, generational_box::BorrowError> { - self.try_read_unchecked().map(Self::Storage::downcast_ref) + self.try_read_unchecked() + .map(Self::Storage::downcast_lifetime_ref) } /// Try to get a reference to the value without checking the lifetime. @@ -80,7 +81,7 @@ pub trait Readable { /// Get the current value of the state without subscribing to updates. If the value has been dropped, this will panic. #[track_caller] fn peek(&self) -> ReadableRef { - Self::Storage::downcast_ref(self.peek_unchecked()) + Self::Storage::downcast_lifetime_ref(self.peek_unchecked()) } /// Clone the inner value and return it. If the value has been dropped, this will panic. diff --git a/packages/signals/src/signal.rs b/packages/signals/src/signal.rs index 2708b7b4f..1c530af29 100644 --- a/packages/signals/src/signal.rs +++ b/packages/signals/src/signal.rs @@ -212,7 +212,9 @@ impl>> Writable for Signal { Write::filter_map(ref_, f) } - fn downcast_mut<'a: 'b, 'b, R: ?Sized + 'static>(mut_: Self::Mut<'a, R>) -> Self::Mut<'b, R> { + fn downcast_lifetime_mut<'a: 'b, 'b, R: ?Sized + 'static>( + mut_: Self::Mut<'a, R>, + ) -> Self::Mut<'b, R> { Write::downcast_lifetime(mut_) } @@ -312,12 +314,14 @@ impl<'a, T: ?Sized + 'static, S: AnyStorage> Write<'a, T, S> { } /// Downcast the lifetime of the mutable reference to the signal's value. + /// + /// This function enforces the variance of the lifetime parameter `'a` in Mut. Rust will typically infer this cast with a concrete type, but it cannot with a generic type. pub fn downcast_lifetime<'b>(mut_: Self) -> Write<'b, T, S> where 'a: 'b, { Write { - write: S::downcast_mut(mut_.write), + write: S::downcast_lifetime_mut(mut_.write), drop_signal: mut_.drop_signal, } } diff --git a/packages/signals/src/write.rs b/packages/signals/src/write.rs index c4b8582e5..2181da3dc 100644 --- a/packages/signals/src/write.rs +++ b/packages/signals/src/write.rs @@ -26,7 +26,9 @@ pub trait Writable: Readable { /// Downcast a mutable reference in a RefMut to a more specific lifetime /// /// This function enforces the variance of the lifetime parameter `'a` in Ref. - fn downcast_mut<'a: 'b, 'b, T: ?Sized + 'static>(mut_: Self::Mut<'a, T>) -> Self::Mut<'b, T>; + fn downcast_lifetime_mut<'a: 'b, 'b, T: ?Sized + 'static>( + mut_: Self::Mut<'a, T>, + ) -> Self::Mut<'b, T>; /// Get a mutable reference to the value. If the value has been dropped, this will panic. #[track_caller] @@ -37,7 +39,7 @@ pub trait Writable: Readable { /// Try to get a mutable reference to the value. #[track_caller] fn try_write(&mut self) -> Result, generational_box::BorrowMutError> { - self.try_write_unchecked().map(Self::downcast_mut) + self.try_write_unchecked().map(Self::downcast_lifetime_mut) } /// Try to get a mutable reference to the value without checking the lifetime. @@ -238,7 +240,7 @@ impl<'a, T: 'static, R: Writable>> Iterator for WritableValueIte self.value.try_write_unchecked().unwrap(), |v: &mut Vec| v.get_mut(index), ) - .map(R::downcast_mut) + .map(R::downcast_lifetime_mut) } }