pub struct EffectAtoms {
pub reads: BTreeSet<DefinitionId>,
pub writes: BTreeSet<DefinitionId>,
pub calls: BTreeSet<String>,
pub direct_calls: BTreeSet<DefinitionId>,
pub creates_fn_values: BTreeSet<DefinitionId>,
pub opaque: bool,
pub emits: bool,
pub tags: bool,
pub faults: bool,
pub faults_refined: bool,
pub param_holes: BTreeSet<u32>,
pub call_fn_args: BTreeMap<(DefinitionId, u32), FnArgOrigins>,
}Expand description
The raw per-definition atoms harvested from one body walk — the inputs the
solve_scc_effects fixpoint closes over. reads/writes/calls are the
direct atoms this body emits; direct_calls are the inferable
(knot/stitch) callees whose rows must be joined in transitively;
creates_fn_values are the targets this body creates fn values for
(Fork A, issue #1726 — structural, fed into the call graph alongside
direct_calls); opaque records that the body performed a call through a
function value whose reaching values were not all created in-project (or
another effects-opaque construct), forcing the pessimal floor.
Fields§
§reads: BTreeSet<DefinitionId>§writes: BTreeSet<DefinitionId>§calls: BTreeSet<String>Directly-called EXTERNAL binding names (call-kind atoms).
direct_calls: BTreeSet<DefinitionId>Inferable (knot/stitch) call targets — the edges the fixpoint follows.
A superset shape of FG-2.1’s call_edges, harvested from the same walk.
creates_fn_values: BTreeSet<DefinitionId>Fork A (docs/decision-log.md 2026-07-28 “Fork A — fn-value
call-graph edges are harvested STRUCTURALLY”, issue #1726): the
inferable targets whose fn values this body creates — every
#fn(target, …) literal in the body, whether or not the value is ever
called here.
Structural, never row-derived. The target of a #fn literal is a
syntactic name, so deciding membership never consults an inferred row
or signature — which is exactly what keeps call_graph_query → scc_membership_query → solve_scc_query → call_graph_query acyclic
(§6.1 fixes every fn value’s row at its creation site, and creation
sites are syntactic). bind(f, …) adds nothing of its own: it copies
an existing value rather than naming a new target.
A subset of Self::direct_calls by construction — the same walk
records a #fn target as a call-graph edge too, which is how these
edges reach the SCC batching and solve_scc_effects with no change
to either. Kept as its own set because “creates a value for g” and
“calls g” are different facts: spec §7’s token table and §8 rung 1’s
reachability slicing both need the creation sites specifically.
Lambda literals are still out of scope: a lambda’s
DefinitionId is now minted at HIR time (hir::stamp_container_ids,
issue #1727 — LIR lowering only reads it, no longer mints it), but a
lambda literal has no index symbol / DefKey of its own, so there is
still nothing here to record it against. Joining it into the SCC
solve is #2152’s job, not this one’s.
opaque: boolThis body calls through a function value whose reaching values were
not all created in-project (or otherwise escapes the static call
graph) — its row is pessimal (spec §3/§4). Fork A (issue #1726)
collapsed this to a real row for the in-project case: a call through a
local whose every write traced to a #fn/bind creation site
narrows to the join over those targets instead. It stays pessimal for
genuinely unknown sources — host callbacks (§6.2) and values loaded
from the heap (§6.3).
emits: boolNS-A2: this body directly contains a content-producing construct
(see EffectRow::emits).
NS-A2: this body directly touches the tag channel (see
EffectRow::tags).
faults: boolNS-A2: this body directly contains a construct that can raise a
turn-terminating fault (see EffectRow::faults).
faults_refined: boolNS-A4 / F29(a): the refined faults bit (see
EffectRow::faults_refined) — the same charge sites with local
type-evidence discharges applied. faults_refined → faults.
param_holes: BTreeSet<u32>§6.1 (issue #1680): the declaration indices of this body’s own
fn-typed params that it calls through — the row variables its
row is parametric in. Becomes EffectRow::holes via
Self::base_row.
Structural, never row-derived, exactly like
Self::creates_fn_values: membership is decided by “the callee of
this call site resolves to param #i of the enclosing definition”,
a syntactic fact, so the call graph stays row-independent (Fork A,
§6.1a).
A param only qualifies when the body cannot have changed what it
holds: ref params are excluded outright (the callee’s own caller
aliases the slot), and so is any param the body assigns to or hands
to a ref slot — for those the call site keeps Self::opaque,
the pre-#1680 behavior.
call_fn_args: BTreeMap<(DefinitionId, u32), FnArgOrigins>§6.1 (issue #1680): the caller half of a row variable — for each
(callee, param index) this body calls with a traceable fn-value
argument, what that argument can hold. solve_scc_effects reads
this to fill the callee row’s EffectRow::holes.
Joined over every call site to that callee in this body (the walk is
flow-insensitive), so two sites passing two different #fn targets
yield both targets and the fill joins both — conservative, per Fork A’s
join-over-writes rule. A position with no entry, or an entry whose
[FnArgOrigins::untraced] is set, cannot fill: the hole takes the
pessimal floor instead.
Recorded only for inferable (knot/stitch) callees — the only definitions that have a row with holes to fill.
Implementations§
Trait Implementations§
Source§impl Clone for EffectAtoms
impl Clone for EffectAtoms
Source§fn clone(&self) -> EffectAtoms
fn clone(&self) -> EffectAtoms
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for EffectAtoms
impl Debug for EffectAtoms
Source§impl Default for EffectAtoms
impl Default for EffectAtoms
Source§fn default() -> EffectAtoms
fn default() -> EffectAtoms
impl Eq for EffectAtoms
Source§impl PartialEq for EffectAtoms
impl PartialEq for EffectAtoms
impl StructuralPartialEq for EffectAtoms
Auto Trait Implementations§
impl Freeze for EffectAtoms
impl RefUnwindSafe for EffectAtoms
impl Send for EffectAtoms
impl Sync for EffectAtoms
impl Unpin for EffectAtoms
impl UnsafeUnpin for EffectAtoms
impl UnwindSafe for EffectAtoms
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.