diff --git a/packages/core/src/scope_context.rs b/packages/core/src/scope_context.rs index 515dd9f65..441abc056 100644 --- a/packages/core/src/scope_context.rs +++ b/packages/core/src/scope_context.rs @@ -17,9 +17,13 @@ pub(crate) struct ScopeContext { pub(crate) height: u32, pub(crate) render_count: Cell, pub(crate) suspended: Cell, - pub(crate) shared_contexts: RefCell>>, + + // Note: the order of the hook and context fields is important. The hooks field must be dropped before the contexts field in case a hook drop implementation tries to access a context. pub(crate) hooks: RefCell>>, pub(crate) hook_index: Cell, + + pub(crate) shared_contexts: RefCell>>, + pub(crate) spawned_tasks: RefCell>, } @@ -69,7 +73,7 @@ impl ScopeContext { /// Schedule an update for any component given its [`ScopeId`]. /// - /// A component's [`ScopeId`] can be obtained from `use_hook` or the [`ScopeState::scope_id`] method. + /// A component's [`ScopeId`] can be obtained from `use_hook` or the [`current_scope_id`] method. /// /// This method should be used when you want to schedule an update for a component pub fn schedule_update_any(&self) -> Arc { diff --git a/packages/core/tests/miri_simple.rs b/packages/core/tests/miri_simple.rs index 8c6a77eae..d02e2e3d2 100644 --- a/packages/core/tests/miri_simple.rs +++ b/packages/core/tests/miri_simple.rs @@ -116,3 +116,28 @@ fn diffing_drops_old() { _ = dom.render_immediate_to_vec(); } + +#[test] +fn hooks_drop_before_contexts() { + fn app() -> Element { + provide_context(123i32); + use_hook(|| { + #[derive(Clone)] + struct ReadsContextOnDrop; + + impl Drop for ReadsContextOnDrop { + fn drop(&mut self) { + let _ = consume_context::(); + } + } + }); + + rsx! { div {} } + } + + let mut dom = VirtualDom::new(app); + + dom.rebuild(&mut dioxus_core::NoOpMutations); + dom.mark_dirty(ScopeId::ROOT); + _ = dom.render_immediate_to_vec(); +}