* map signals mutably * boxed signals * remove mutable borrow type from boxed writable * improve map mut example * restore boxed_mut helper * make boxed readable/writable types copy * Move away from the ReadOnlySignal alias in examples * automatically convert Write * Fix some tests * ReadSignal and WriteSignal * move read only signal alias * make maps copy * store prototype * implement derive macro * Handle generics in the derive macro * Make Selector boxable * derive boxed conversion * Get rid of store type * Remove hardcoded type from derive macro * selector -> store * Refactor store implementation * more vec methods * todo mvc store example * Implement Storable for HashMap * fix write * restore sorting logic in todomvc * derive readable and writable * improve todomvc store example * Result store * Option store * collect dead subscribers * fix clippy and formatting * recognize some common foreign types automatically * fix foreign stores in props * slice and array selectors * clean up store example * writable is child owned * box selector * read and write to builtins * re-use the proc macro in the derive macro * Switch to a extension trait based approach * switch to extension traits in the derive macro * transposed method * derive enums * Expose Store::new * remove stores from the prelude * More consistent naming scheme for SelectorScope methods * document hashmap methods * document index extension * document option ext * document result ext * document slice extension * document the vec extension * make more methods borrow the store mutably * Move to impls to have higher priority over the builtin write extension traits * fix deadlock * finish stores documentation * Document the store macro * cleanup docs and organization * finish derive docs * fix typo * fix clippy * fix doc tests * fix derive macro with generics * fix clippy * test and fix empty structs * clean up todomvc store example * default to a boxed store writer to make it easier to type when providing to the context api * fix cargo doc * fix clippy in store example * relax generational box lifetime bounds * relax bounds * relax signal bounds * fix compilation * read store * relax bounds on default store impls * fix enum derive * Convert to readsignal and writesignal automatically * simplify type matching logic * add write store * unsized stores * shrink the path vec type * use more concrete types * remove opaque types * remove copy bounds * use lens as generic name everywhere * more consistent borrow semantics * use a concrete type for the signal metadata and mention references in the map docs * improve todomvc store docs * document store derive macro internals * refactor macro * improve selector node documentation * fix clippy * add btreemap * fix doc tests * more option methods * fix doc * fix clippy * add a bunch more result methods * add a bunch of bounds to the iterators * fix clippy * remove option from subscribers * add store macro to generate extension traits * fix store example * fix deadlock * fix docs * fix doc tests * fix clippy * add stores to public api * add store macro, and then update todomvc_store example --------- Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
56 lines
2.1 KiB
Rust
56 lines
2.1 KiB
Rust
//! Warnings that can be triggered by suspicious usage of signals
|
|
|
|
use warnings::warning;
|
|
|
|
/// A warning that is triggered when a copy value is used in a higher scope that it is owned by
|
|
#[warning]
|
|
pub fn copy_value_hoisted<T: 'static, S: generational_box::Storage<T> + 'static>(
|
|
value: &crate::CopyValue<T, S>,
|
|
caller: &'static std::panic::Location<'static>,
|
|
) {
|
|
let origin_scope = value.origin_scope;
|
|
if let Ok(current_scope) = dioxus_core::current_scope_id() {
|
|
// If the current scope is a descendant of the origin scope or is the same scope, we don't need to warn
|
|
if origin_scope == current_scope || current_scope.is_descendant_of(origin_scope) {
|
|
return;
|
|
}
|
|
let create_location = value.value.created_at().unwrap();
|
|
let broken_example = include_str!("../docs/hoist/error.rs");
|
|
let fixed_example = include_str!("../docs/hoist/fixed_list.rs");
|
|
|
|
// Otherwise, warn that the value is being used in a higher scope and may be dropped
|
|
tracing::warn!(
|
|
r#"A Copy Value created in {origin_scope:?} (at {create_location}). It will be dropped when that scope is dropped, but it was used in {current_scope:?} (at {caller}) which is not a descendant of the owning scope.
|
|
This may cause reads or writes to fail because the value is dropped while it still held.
|
|
|
|
Help:
|
|
Copy values (like CopyValue, Signal, Memo, and Resource) are owned by the scope they are created in. If you use the value in a scope that may be dropped after the origin scope,
|
|
it is very easy to use the value after it has been dropped. To fix this, you can move the value to the parent of all of the scopes that it is used in.
|
|
|
|
Broken example ❌:
|
|
```rust
|
|
{broken_example}
|
|
```
|
|
|
|
Fixed example ✅:
|
|
```rust
|
|
{fixed_example}
|
|
```"#
|
|
);
|
|
}
|
|
}
|
|
|
|
// Include the examples from the warning to make sure they compile
|
|
#[test]
|
|
#[allow(unused)]
|
|
fn hoist() {
|
|
mod broken {
|
|
use dioxus::prelude::*;
|
|
include!("../docs/hoist/error.rs");
|
|
}
|
|
mod fixed {
|
|
use dioxus::prelude::*;
|
|
include!("../docs/hoist/fixed_list.rs");
|
|
}
|
|
}
|