From d4768d606f10b6afc788d566a63be2b964b462ee Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Tue, 8 Sep 2026 13:23:52 +0000 Subject: [PATCH] Justify the unsafe sites in the arena, record and graphic glue --- node-graph/libraries/core-types/src/arena.rs | 11 ++++++++ .../libraries/core-types/src/attribute.rs | 3 +++ node-graph/libraries/core-types/src/list.rs | 5 ++++ .../libraries/core-types/src/record/input.rs | 3 +++ .../libraries/core-types/src/record/layout.rs | 25 +++++++++++++++++++ .../libraries/core-types/src/record/owned.rs | 10 ++++++++ .../core-types/src/record/promote.rs | 2 ++ .../libraries/core-types/src/record/route.rs | 2 ++ .../libraries/core-types/src/record/run.rs | 21 ++++++++++++++++ .../libraries/graphic-types/src/artboard.rs | 5 ++++ .../graphic-types/src/graphic/glue.rs | 7 ++++++ 11 files changed, 94 insertions(+) diff --git a/node-graph/libraries/core-types/src/arena.rs b/node-graph/libraries/core-types/src/arena.rs index 5ae9507fed..f39958d511 100644 --- a/node-graph/libraries/core-types/src/arena.rs +++ b/node-graph/libraries/core-types/src/arena.rs @@ -54,6 +54,9 @@ struct DropEntry { /// The glue a tombstoned entry carries: its payload was moved to another arena, /// which now owns the obligation. +/// +/// # Safety +/// None: the payload is neither read nor dropped, so any pointer is accepted. unsafe fn inert(_: *mut u8) {} /// The entry parking `offset`, `None` where the arena holds no obligation for @@ -237,11 +240,15 @@ impl Arena { // Built before the write so an unencodable offset drops `value` here // rather than stranding it in the arena without drop glue. let weak = ArenaWeak::new(self.generation(), offset)?; + // SAFETY: `reserve` returned `offset`, so it is within the backbone. let ptr = unsafe { self.base().add(offset) }.cast::(); // SAFETY: freshly reserved, aligned, in-bounds, unaliased. unsafe { ptr.write(value) }; if std::mem::needs_drop::() { + /// # Safety + /// `p` must address the live `T` this entry was registered for. unsafe fn glue(p: *mut u8) { + // SAFETY: the caller's contract. unsafe { p.cast::().drop_in_place() } } self.drops.lock().unwrap().push(DropEntry { offset, type_of, drop_fn: glue::, retained }); @@ -315,7 +322,10 @@ impl Arena { let parked = std::mem::replace(&mut entries[entry].retained, 0); entries[entry].drop_fn = inert; drop(entries); + /// # Safety + /// `p` must address the live `T` this entry was registered for. unsafe fn glue(p: *mut u8) { + // SAFETY: the caller's contract. unsafe { p.cast::().drop_in_place() } } dst.drops.lock().unwrap().push(DropEntry { @@ -345,6 +355,7 @@ impl Arena { pub fn alloc_scratch(&self, len: usize) -> Option<&mut [MaybeUninit]> { let size = size_of::().checked_mul(len)?; let offset = self.reserve(size, align_of::())?; + // SAFETY: `reserve` returned `offset`, so it is within the backbone. let ptr = unsafe { self.base().add(offset) }.cast::>(); // SAFETY: exclusive region; lifetime tied to `&self`, and `reset` takes // `&mut self`, so the slice cannot outlive the generation. diff --git a/node-graph/libraries/core-types/src/attribute.rs b/node-graph/libraries/core-types/src/attribute.rs index ab6217d9ec..1a727e965c 100644 --- a/node-graph/libraries/core-types/src/attribute.rs +++ b/node-graph/libraries/core-types/src/attribute.rs @@ -199,12 +199,15 @@ where crate::record::FieldWrite::of::(level) } +/// # Safety +/// `dst` must address a live field of `A`'s value type. unsafe fn write_stored(stored: &dyn AnyAttributeValue, dst: *mut u8, arena: &crate::arena::Arena) -> Option<()> { if A::from_stored(stored.as_any()).is_none() { // A wrong-typed stored value reads as absent, so the field keeps its default. return Some(()); } match A::REPARK { + // SAFETY: the caller's contract; the glue is this marker's own. Some(repark) => unsafe { repark(stored, dst, arena) }, None => { let value = A::from_stored(stored.as_any()).expect("checked above"); diff --git a/node-graph/libraries/core-types/src/list.rs b/node-graph/libraries/core-types/src/list.rs index 839631f270..023e688270 100644 --- a/node-graph/libraries/core-types/src/list.rs +++ b/node-graph/libraries/core-types/src/list.rs @@ -375,6 +375,7 @@ impl CacheHash for AttributeDyn { } } +// SAFETY: the type carries no lifetime, so it is its own static form. unsafe impl StaticType for AttributeDyn { type Static = Self; } @@ -418,6 +419,7 @@ impl CacheHash for AttributeValueDyn { } } +// SAFETY: as for AttributeDyn. unsafe impl StaticType for AttributeValueDyn { type Static = Self; } @@ -501,6 +503,7 @@ impl CacheHash for ListDyn { } } +// SAFETY: as for AttributeDyn. unsafe impl StaticType for ListDyn { type Static = Self; } @@ -1190,6 +1193,8 @@ impl ApplyTransform for List { } } +// SAFETY: the list carries its lifetime only through T, so substituting T's +// static form substitutes the list's and keeps the layout identical. unsafe impl StaticType for List { type Static = List; } diff --git a/node-graph/libraries/core-types/src/record/input.rs b/node-graph/libraries/core-types/src/record/input.rs index a22bec88c2..3df6daa86c 100644 --- a/node-graph/libraries/core-types/src/record/input.rs +++ b/node-graph/libraries/core-types/src/record/input.rs @@ -214,6 +214,7 @@ impl<'a, 'e, N> RecordInput<'a, 'e, N> { /// `rec` must be a record of the layout the offsets were resolved against /// and `El` its element type; both are proven at wiring. unsafe fn element_only(rec: Rec<'_>, _reads: &[Option]) -> El { + // SAFETY: the caller's contract. unsafe { read_element::(rec) } } @@ -516,6 +517,8 @@ impl RecordExtract { // The element copies out by value, so the input's claim dies with // the scope. let scope = frames.scope(); + // SAFETY: the served value is a record of `self.layout`, whose element is + // `El` by the wiring that built this extract. serve_input(&self.edge, input, &scope).map(|value| unsafe { read_element::(self.layout.rec(&value)) }) } } diff --git a/node-graph/libraries/core-types/src/record/layout.rs b/node-graph/libraries/core-types/src/record/layout.rs index 9ab27042cd..8946895ced 100644 --- a/node-graph/libraries/core-types/src/record/layout.rs +++ b/node-graph/libraries/core-types/src/record/layout.rs @@ -28,11 +28,17 @@ impl FieldWrite { where A::Value<'static>: graphene_hash::CacheHash + PartialEq + 'static, { + /// # Safety + /// `ptr` must address a live `V`. unsafe fn content_hash(ptr: *const u8, state: &mut dyn core::hash::Hasher) { let mut state = state; + // SAFETY: the caller's contract. unsafe { &*ptr.cast::() }.cache_hash(&mut state); } + /// # Safety + /// `a` and `b` must both address a live `V`. unsafe fn content_eq(a: *const u8, b: *const u8) -> bool { + // SAFETY: the caller's contract. unsafe { *a.cast::() == *b.cast::() } } Self { @@ -132,12 +138,18 @@ impl Eq for ElementWrite {} impl Default for ElementWrite { fn default() -> Self { + /// # Safety + /// None: the empty element has no bytes, so nothing is read. unsafe fn clone_out(_ptr: *const u8) -> Box { Box::new(()) } + /// # Safety + /// None: nothing is written, the empty element having no slot. unsafe fn repark(_value: &(dyn std::any::Any + Send + Sync), _dst: *mut u8, _arena: &crate::arena::Arena) -> Option<()> { Some(()) } + /// # Safety + /// None: the move always declines, so `parked` is never read. unsafe fn park_move(_parked: *const u8, _promotion: &Promotion<'_>) -> Option<*const u8> { None } @@ -508,11 +520,14 @@ pub fn element_write() -> Ele where T::Static: Clone + Send + Sync, { + /// # Safety + /// `ptr` must address a live element of `T` in the form [`element_parked`] picks. unsafe fn clone_out(ptr: *const u8) -> Box where T::Static: Clone + Send + Sync, { if let Some(deep) = deep_element_glue(std::any::TypeId::of::()) { + // SAFETY: the caller's contract; the glue is registered for this element type. return unsafe { (deep.clone_out)(ptr) }; } // SAFETY: a lifetime-carrying element type registers deep glue, so this @@ -522,11 +537,15 @@ where // which is where a missed wasm registration export is caught. Box::new(unsafe { erase_static(read_element::(Rec::new(ptr))) }) } + /// # Safety + /// `dst` must be fresh element storage of a record whose element is `T`, and + /// `value` must be the clone-out this glue produced for that element type. unsafe fn repark(value: &(dyn std::any::Any + Send + Sync), dst: *mut u8, arena: &crate::arena::Arena) -> Option<()> where T::Static: Clone + Send + Sync, { if let Some(deep) = deep_element_glue(std::any::TypeId::of::()) { + // SAFETY: the caller's contract; the glue is registered for this element type. return unsafe { (deep.repark)(value, dst, arena) }; } let retained = retained_measure(std::any::TypeId::of::()).map_or(0, |measure| measure(value)); @@ -571,11 +590,17 @@ pub fn element_write_hashed(ptr: *const u8, state: &mut dyn core::hash::Hasher) { let mut state = state; + // SAFETY: the caller's contract. unsafe { borrow_element::(Rec::new(ptr)) }.cache_hash(&mut state); } + /// # Safety + /// `a` and `b` must each address a live element of `T` in that same form. unsafe fn content_eq(a: *const u8, b: *const u8) -> bool { + // SAFETY: the caller's contract. unsafe { borrow_element::(Rec::new(a)) == borrow_element::(Rec::new(b)) } } ElementWrite { diff --git a/node-graph/libraries/core-types/src/record/owned.rs b/node-graph/libraries/core-types/src/record/owned.rs index 68614017f2..9077a9e883 100644 --- a/node-graph/libraries/core-types/src/record/owned.rs +++ b/node-graph/libraries/core-types/src/record/owned.rs @@ -113,17 +113,21 @@ impl OwnedRecord { // The element-to-field seam is never written, so the copy stays untyped: // a `&[u8]` over the frame would read those bytes. let mut staged = Vec::::with_capacity(layout.size); + // SAFETY: the caller's contract sizes the record at `layout.size`, which + // is the capacity just reserved, so the copy fills exactly the staging. let bytes = unsafe { std::ptr::copy_nonoverlapping(rec.ptr(), staged.as_mut_ptr(), layout.size); staged.set_len(layout.size); staged.into_boxed_slice() }; + // SAFETY: the caller's contract; a parked element sits at offset 0. let element = layout.element.parked.then(|| unsafe { (layout.element.clone_out)(rec.ptr()) }); let fields = layout .fields .iter() .enumerate() .filter(|(_, field)| field.repark.is_some()) + // SAFETY: the caller's contract; each field reads its own descriptor's offset. .map(|(index, field)| (index, field.type_id, deepen_field_value(unsafe { (field.read_erased)(rec.ptr().add(field.offset)) }))) .collect(); OwnedRecord { bytes, element, fields } @@ -146,15 +150,21 @@ impl OwnedRecord { self.write_into(layout, slot.dst(), arena) } + /// `dst` is a claimed frame of `layout`, and `replay_into`'s asserts have + /// established that `layout` is the one the copy was taken at. fn write_into(&self, layout: &Layout, dst: *mut u8, arena: &crate::arena::Arena) -> Option<()> { + // SAFETY: the copy is `layout.size` bytes and the claim is a frame of it. unsafe { std::ptr::copy_nonoverlapping(self.bytes.as_ptr(), dst, self.bytes.len()) }; if let Some(element) = &self.element { + // SAFETY: the element was cloned out of this layout's own slot at offset 0. unsafe { (layout.element.repark)(&**element, dst, arena) }?; } for (index, _, value) in &self.fields { let field = &layout.fields[*index]; let repark = field.repark.expect("copied fields carry re-park glue"); let resident = replay_field_value(&**value, arena)?; + // SAFETY: the asserts matched this index's field type, so the glue and + // the value agree; the write lands in that field's own region. unsafe { repark(resident.as_deref().unwrap_or(&**value), dst.add(field.offset), arena) }?; } Some(()) diff --git a/node-graph/libraries/core-types/src/record/promote.rs b/node-graph/libraries/core-types/src/record/promote.rs index edc00dc4e5..19fc45e1e2 100644 --- a/node-graph/libraries/core-types/src/record/promote.rs +++ b/node-graph/libraries/core-types/src/record/promote.rs @@ -99,6 +99,7 @@ pub(in crate::record) unsafe fn promote_record(layout: &Layout, dst: *mut u8, pr None => { // SAFETY: as above, and the clone owns its content. let owned = unsafe { (layout.element.clone_out)(dst.cast_const()) }; + // SAFETY: the clone is this element's own type, back into its slot. unsafe { (layout.element.repark)(&*owned, dst, promotion.persistent) }?; } }, @@ -243,6 +244,7 @@ impl MaterializedSpan { // SAFETY: the caller's contract on the lane, into the lane's own // region of the freshly reserved slab. let dst = unsafe { base.add(lane * stride) }; + // SAFETY: as above; `layout.size` bytes of a lane fit its own stride. unsafe { std::ptr::copy_nonoverlapping(batch.get(lane).rec().ptr(), dst, layout.size) }; // SAFETY: the copy images a record of this layout. unsafe { promote_record(layout, dst, promotion) }?; diff --git a/node-graph/libraries/core-types/src/record/route.rs b/node-graph/libraries/core-types/src/record/route.rs index e898741f9a..b6635f192c 100644 --- a/node-graph/libraries/core-types/src/record/route.rs +++ b/node-graph/libraries/core-types/src/record/route.rs @@ -51,6 +51,8 @@ impl SourcePlan { /// 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> { + // SAFETY: the caller's contract; the plan's moves and fills name only + // offsets of the layouts it was built from. unsafe { apply_plan(src, dst, &self.moves); for (offset, bytes) in &self.fills { diff --git a/node-graph/libraries/core-types/src/record/run.rs b/node-graph/libraries/core-types/src/record/run.rs index 9038f9059a..7c9bf4443e 100644 --- a/node-graph/libraries/core-types/src/record/run.rs +++ b/node-graph/libraries/core-types/src/record/run.rs @@ -96,6 +96,8 @@ impl<'e> RunBuilder<'e> { // `lane` is below `len`; the element slot and each field's region are // disjoint parts of this lane. let base = unsafe { self.frames.add(lane * stride) }; + // SAFETY: the element slot is fresh, and the assert above matched `T` to + // the layout's element type. unsafe { write_element(base, element, self.arena) }?; for field in &self.layout.fields { // SAFETY: as above; the field region is within the lane. @@ -240,6 +242,7 @@ impl<'e> GroupItem<'e> { for lane in 0..batch.len() { // SAFETY: both sides hold `len` lanes at the shared layout's stride. let dst = unsafe { frames.add(lane * stride) }; + // SAFETY: as above; the scratch was reserved for exactly these lanes. unsafe { std::ptr::copy_nonoverlapping(batch.get(lane).rec().ptr(), dst, stride) }; if parked { // SAFETY: the copy images a live record of this layout. @@ -355,6 +358,7 @@ impl<'e> GroupItem<'e> { .layout .element .parked + // SAFETY: as above; a parked element sits at each lane's offset 0. .then(|| (0..self.len).map(|lane| unsafe { (self.layout.element.clone_out)(frames.add(lane * stride)) }).collect()); let fields = self .layout @@ -363,6 +367,7 @@ impl<'e> GroupItem<'e> { .enumerate() .filter(|(_, field)| field.repark.is_some()) .map(|(index, field)| { + // SAFETY: as above; each lane reads this descriptor's own offset. let mut values: Vec<_> = (0..self.len).map(|lane| unsafe { (field.read_erased)(frames.add(lane * stride + field.offset)) }).collect(); if let Some(glue) = values.first().and_then(|value| deep_field_glue(value.as_any().type_id())) { for value in &mut values { @@ -400,6 +405,7 @@ impl<'e> GroupItem<'e> { unsafe { std::ptr::copy_nonoverlapping(owned.bytes.as_ptr(), frames, owned.bytes.len()) }; if let Some(elements) = &owned.elements { for (lane, element) in elements.iter().enumerate() { + // SAFETY: as above; the clone is this element's own type, into its lane's slot. unsafe { (self.layout.element.repark)(&**element, frames.add(lane * stride), arena) }?; } } @@ -408,6 +414,8 @@ impl<'e> GroupItem<'e> { let repark = field.repark.expect("copied fields carry re-park glue"); let glue = values.first().and_then(|value| deep_field_glue(value.as_any().type_id())); for (lane, value) in values.iter().enumerate() { + // SAFETY: the copy took these values through this field's own glue, + // so each writes its own type into its lane's region of the field. match glue { Some(glue) => match (glue.replay)(&**value, arena)? { Some(resident) => unsafe { repark(&*resident, frames.add(lane * stride + field.offset), arena) }?, @@ -600,14 +608,20 @@ impl<'e> Group<'e> { /// touches. The element always carries glue (`assert_element_glue`) and /// `FieldWrite::of` always installs field glue, so a padded value's own /// padding never reaches the byte fallback either. +/// +/// # Safety +/// `a` and `b` must both be live records of `layout`. unsafe fn record_content_eq(layout: &Layout, a: *const u8, b: *const u8) -> bool { + // SAFETY: the caller's contract; each call reads a written span of the layout. let bytes_eq = |offset: usize, size: usize| unsafe { std::slice::from_raw_parts(a.add(offset), size) == std::slice::from_raw_parts(b.add(offset), size) }; let element = match layout.element.content_eq { + // SAFETY: the caller's contract; the glue is the element's own. Some(eq) => unsafe { eq(a, b) }, None => bytes_eq(0, layout.element.size), }; element && layout.fields.iter().all(|field| match field.content_eq { + // SAFETY: as above, at this descriptor's own offset. Some(eq) => unsafe { eq(a.add(field.offset), b.add(field.offset)) }, None => bytes_eq(field.offset, field.size), }) @@ -615,14 +629,21 @@ unsafe fn record_content_eq(layout: &Layout, a: *const u8, b: *const u8) -> bool /// Hashes one record region of `layout` by content, with the byte fallback /// of [`record_content_eq`]. +/// +/// # Safety +/// `ptr` must be a live record of `layout`. unsafe fn record_content_hash(layout: &Layout, ptr: *const u8, state: &mut dyn core::hash::Hasher) { match layout.element.content_hash { + // SAFETY: the caller's contract; the glue is the element's own. Some(hash) => unsafe { hash(ptr, state) }, + // SAFETY: as above; the element's own bytes are written. None => state.write(unsafe { std::slice::from_raw_parts(ptr, layout.element.size) }), } for field in &layout.fields { match field.content_hash { + // SAFETY: as above, at this descriptor's own offset. Some(hash) => unsafe { hash(ptr.add(field.offset), state) }, + // SAFETY: as above; the field's own bytes are written. None => state.write(unsafe { std::slice::from_raw_parts(ptr.add(field.offset), field.size) }), } } diff --git a/node-graph/libraries/graphic-types/src/artboard.rs b/node-graph/libraries/graphic-types/src/artboard.rs index 1700c00052..e2193b70d3 100644 --- a/node-graph/libraries/graphic-types/src/artboard.rs +++ b/node-graph/libraries/graphic-types/src/artboard.rs @@ -50,6 +50,7 @@ impl<'e> Artboard<'e> { /// # Safety /// `ptr` must point at a live parked `Artboard` element field. unsafe fn deep_clone_artboard(ptr: *const u8) -> Box { + // SAFETY: the caller's contract. let artboard = unsafe { core_types::record::borrow_element::(core_types::record::Rec::new(ptr)) }; let mut content = artboard.0.clone(); for element in content.iter_element_values_mut() { @@ -72,6 +73,7 @@ unsafe fn deep_repark_artboard(value: &(dyn std::any::Any + Send + Sync), dst: * *element = crate::graphic::map_groups_to_resident(element, arena)?; } crate::graphic::map_attribute_groups_to_resident(&mut content, arena)?; + // SAFETY: the caller's contract on `dst`; the replayed content is an `Artboard`. unsafe { core_types::record::write_element(dst, Artboard(content), arena) } } @@ -83,12 +85,14 @@ unsafe fn deep_repark_artboard(value: &(dyn std::any::Any + Send + Sync), dst: * /// `src` must point at a live parked `Artboard` element field, and `dst` at /// the element field the promoted reference is written to. unsafe fn promote_artboard(src: *const u8, dst: *mut u8, promotion: &core_types::record::Promotion<'_>) -> Option<()> { + // SAFETY: the caller's contract on `src`. let artboard = unsafe { core_types::record::borrow_element::(core_types::record::Rec::new(src)) }; if !crate::graphic::list_contains_groups(&artboard.0) { // SAFETY: a parked element slot holds one reference at offset 0, and // content no group is reachable from, elements and item attribute values // alike, owns all of itself. let header = unsafe { src.cast::<*const u8>().read() }; + // SAFETY: as above; the group-free check establishes the own-all-content half. if let Some(moved) = unsafe { promotion.move_park::(header, 0) } { // SAFETY: as above, into the promoted image's own element slot. unsafe { dst.cast::<*const Artboard>().write(moved) }; @@ -101,6 +105,7 @@ unsafe fn promote_artboard(src: *const u8, dst: *mut u8, promotion: &core_types: content.push(core_types::list::Item::from_parts(crate::graphic::map_groups_to_persistent(&element, promotion)?, attributes)); } crate::graphic::map_attribute_groups_to_persistent(&mut content, promotion)?; + // SAFETY: the caller's contract on `dst`; the promoted content is an `Artboard`. unsafe { core_types::record::write_element(dst, Artboard(content), promotion.persistent()) } } diff --git a/node-graph/libraries/graphic-types/src/graphic/glue.rs b/node-graph/libraries/graphic-types/src/graphic/glue.rs index 2ec75b9cac..aa1f66b5c5 100644 --- a/node-graph/libraries/graphic-types/src/graphic/glue.rs +++ b/node-graph/libraries/graphic-types/src/graphic/glue.rs @@ -54,6 +54,7 @@ pub fn map_groups_to_resident<'a>(graphic: &Graphic<'a>, arena: &'a core_types:: /// # Safety /// `ptr` must point at a live parked `Graphic` element field. unsafe fn deep_clone_graphic(ptr: *const u8) -> Box { + // SAFETY: the caller's contract. let graphic = unsafe { core_types::record::borrow_element::(core_types::record::Rec::new(ptr)) }; Box::new(map_groups_to_owned(graphic)) } @@ -68,6 +69,7 @@ unsafe fn deep_repark_graphic(value: &(dyn std::any::Any + Send + Sync), dst: *m let graphic = value.downcast_ref::().expect("an element replays at its own type"); let resident = map_groups_to_resident(graphic, arena)?; let retained = graphic_retained_heap(&resident); + // SAFETY: the caller's contract; the resident form is a `Graphic` for `dst`. unsafe { core_types::record::write_element_sized(dst, resident, arena, retained) } } @@ -165,12 +167,14 @@ pub(crate) fn map_attribute_groups_to_persistent(list: &mut List>, p /// `src` must point at a live parked `Graphic` element field, and `dst` at the /// element field the promoted reference is written to. unsafe fn promote_graphic(src: *const u8, dst: *mut u8, promotion: &core_types::record::Promotion<'_>) -> Option<()> { + // SAFETY: the caller's contract on `src`. let graphic = unsafe { core_types::record::borrow_element::(core_types::record::Rec::new(src)) }; if !graphic_contains_groups(graphic) { // SAFETY: a parked element slot holds one reference at offset 0, and a // graphic no group is reachable from, elements and item attribute values // alike, owns all of its content. let header = unsafe { src.cast::<*const u8>().read() }; + // SAFETY: as above; the group-free check establishes the own-all-content half. if let Some(moved) = unsafe { promotion.move_park::>(header, graphic_retained_heap(graphic)) } { // SAFETY: as above, into the promoted image's own element slot. unsafe { dst.cast::<*const Graphic<'static>>().write(moved) }; @@ -179,6 +183,7 @@ unsafe fn promote_graphic(src: *const u8, dst: *mut u8, promotion: &core_types:: } let promoted = map_groups_to_persistent(graphic, promotion)?; let retained = graphic_retained_heap(&promoted); + // SAFETY: the caller's contract on `dst`; the promoted form is a `Graphic`. unsafe { core_types::record::write_element_sized(dst, promoted, promotion.persistent(), retained) } } @@ -270,6 +275,8 @@ fn deep_repark_graphic_list(value: &dyn core_types::list::AnyAttributeValue, are *element = map_groups_to_resident(element, arena)?; } map_attribute_groups_to_resident(&mut list, arena)?; + // SAFETY: every group the clone carried, in an element or an item attribute + // value, now names `arena`, whose borrow the replayed field is read at. let list = unsafe { core_types::record::erase_static(list) }; Some(Some(Box::new(Some(list)))) }