From 0fc4424a09e15402973381cca7e323b71f3e65d9 Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Mon, 7 Sep 2026 16:11:56 +0000 Subject: [PATCH] State the disjointness a plan's copies require --- node-graph/libraries/core-types/src/record/access.rs | 4 +++- node-graph/libraries/core-types/src/record/route.rs | 4 ++-- node-graph/libraries/core-types/src/record/serve.rs | 9 ++++++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/node-graph/libraries/core-types/src/record/access.rs b/node-graph/libraries/core-types/src/record/access.rs index caba698705..7da95ace94 100644 --- a/node-graph/libraries/core-types/src/record/access.rs +++ b/node-graph/libraries/core-types/src/record/access.rs @@ -221,7 +221,9 @@ pub(in crate::record) unsafe fn lift_poll_into<'e, T: Send + Sync + dyn_any::Sta /// # Safety /// `src` must be a record of the plan's source layout and `dst` a buffer of -/// the plan's target layout; both are proven at wiring. +/// the plan's target layout; both are proven at wiring. The two records must +/// not overlap: a plan routinely carries identity moves, so each entry copies +/// non-overlapping and an aliasing pair is undefined on the first copy. pub unsafe fn apply_plan(src: Rec<'_>, dst: *mut u8, plan: &[(usize, usize, usize)]) { for &(from, to, size) in plan { unsafe { std::ptr::copy_nonoverlapping(src.ptr().add(from), dst.add(to), size) }; diff --git a/node-graph/libraries/core-types/src/record/route.rs b/node-graph/libraries/core-types/src/record/route.rs index 3a67e16a33..e898741f9a 100644 --- a/node-graph/libraries/core-types/src/record/route.rs +++ b/node-graph/libraries/core-types/src/record/route.rs @@ -48,8 +48,8 @@ impl SourcePlan { /// # Safety /// `src` must be a record of this plan's source layout and `dst` a - /// buffer of the plan's union layout. The returned view borrows `dst`, so - /// `'d` must not outlive it. + /// buffer of the plan's union layout that does not overlap `src`. The + /// returned view borrows `dst`, so `'d` must not outlive it. pub unsafe fn translate<'d>(&self, src: Rec<'_>, dst: *mut u8) -> Rec<'d> { unsafe { apply_plan(src, dst, &self.moves); diff --git a/node-graph/libraries/core-types/src/record/serve.rs b/node-graph/libraries/core-types/src/record/serve.rs index f21d8099e3..65bdc80f9c 100644 --- a/node-graph/libraries/core-types/src/record/serve.rs +++ b/node-graph/libraries/core-types/src/record/serve.rs @@ -119,7 +119,9 @@ impl<'e, 'l> FrameClaim<'e, 'l> { /// /// # Safety /// `src` must be a live record of the plan's source layout, and the plan - /// must be the wiring-resolved plan of this frame's layout. + /// must be the wiring-resolved plan of this frame's layout. `src` must not + /// overlap this frame; an input's frame is split off beyond the claim, so + /// serving the source through [`Self::frames`] establishes it. pub unsafe fn carry(&mut self, src: Rec<'_>, plan: &[(usize, usize, usize)]) { unsafe { apply_plan(src, self.dst(), plan) }; self.filled_fields = true; @@ -219,8 +221,9 @@ impl<'e, 'l> FrameClaim<'e, 'l> { /// Translates a source record into the frame through a wiring-resolved plan. /// /// # Safety - /// `src` must be a live record of `plan`'s source layout, and `plan` must - /// translate into this frame's layout. + /// `src` must be a live record of `plan`'s source layout, `plan` must + /// translate into this frame's layout, and `src` must not overlap this + /// frame, as [`Self::carry`] requires. pub unsafe fn translate(&mut self, src: Rec<'_>, plan: &SourcePlan) { unsafe { plan.translate(src, self.dst()) }; self.filled_fields = true;