sim_kernel/env/fork.rs
1//! Seeded-context forking: [`Cx::fork_from_seed`].
2
3use crate::Cx;
4
5impl Cx {
6 /// Forks a fresh, independently-seated context from `self` used as a seed.
7 ///
8 /// The fork is a brand-new [`Cx`] (with its own [`GrantSeat`] identity, its
9 /// own stores and ledgers) that carries a copy of the seed's evaluation
10 /// surface: the eval policy and factory it is built from, plus the seed's
11 /// environment, behavior registry, source registry, promotion-search limits,
12 /// control policy, and macro expander. The seed's granted capabilities are
13 /// re-granted into the fork through the fork's own host seat, so the fork
14 /// starts with the same authority without sharing the seed's mutable state.
15 ///
16 /// This generalizes the per-consumer `clone_stream_cx` / `clone_server_cx`
17 /// helpers into one kernel primitive; it is a strict superset (it copies the
18 /// control policy and macro expander that only some of those helpers did).
19 ///
20 /// The data substrate (datum/fact/handle stores, effect ledger, load claims,
21 /// diagnostics) is intentionally *not* copied: those are per-context runtime
22 /// state, and a fork begins with the fresh empty stores of [`Cx::new`].
23 ///
24 /// [`GrantSeat`]: crate::GrantSeat
25 pub fn fork_from_seed(&self, handle_seed: crate::HandleSeed) -> Cx {
26 let (mut fork, seat) =
27 Cx::new_seated(self.eval_policy_ref(), self.factory_ref(), handle_seed);
28 *fork.env_mut() = self.env().clone();
29 *fork.registry_mut() = self.registry().clone();
30 *fork.sources_mut() = self.sources().clone();
31 fork.set_promotion_search_limits(self.promotion_search_limits());
32 fork.set_control_policy(self.control_policy_ref());
33 if let Some(expander) = self.macro_expander_ref() {
34 fork.set_macro_expander(expander);
35 }
36 for capability in self.capabilities().iter() {
37 seat.grant(&mut fork, capability.clone())
38 .expect("fork seat grants into its own Cx");
39 }
40 fork
41 }
42}