facet_reflect/partial/
mod.rs

1//! Partial value construction for dynamic reflection
2//!
3//! This module provides APIs for incrementally building values through reflection,
4//! particularly useful when deserializing data from external formats like JSON or YAML.
5//!
6//! # Overview
7//!
8//! The `Partial` type (formerly known as `Wip` - Work In Progress) allows you to:
9//! - Allocate memory for a value based on its `Shape`
10//! - Initialize fields incrementally in a type-safe manner
11//! - Handle complex nested structures including structs, enums, collections, and smart pointers
12//! - Build the final value once all required fields are initialized
13//!
14//! # API Changes
15//!
16//! Recent API improvements include:
17//! - **Renamed from `Wip` to `Partial`** for better clarity about its purpose
18//! - **Method naming changes**:
19//!   - `push()` โ†’ `begin()` - Start working on a nested value
20//!   - `pop()` โ†’ `end()` - Finish working on a nested value
21//!   - camelCase methods โ†’ snake_case (Rust convention)
22//! - **New convenience methods**:
23//!   - `set_nth_field()` - Set a field by index
24//!   - `set_field()` - Set a field by name
25//!   - `set_variant()` - Set enum variant
26//!   - `begin_nth_field()` - Begin working on a field by index
27//!   - `begin_field()` - Begin working on a field by name
28//!
29//! # Basic Usage
30//!
31//! ```no_run
32//! # use facet_reflect::Partial;
33//! # use facet_core::{Shape, Facet};
34//! # fn example<T: Facet<'static>>() -> Result<(), Box<dyn std::error::Error>> {
35//! // Allocate memory for a struct
36//! let mut partial = Partial::alloc::<T>()?;
37//!
38//! // Set simple fields
39//! partial.set_field("name", "Alice")?;
40//! partial.set_field("age", 30u32)?;
41//!
42//! // Work with nested structures
43//! partial.begin_field("address")?;
44//! partial.set_field("street", "123 Main St")?;
45//! partial.set_field("city", "Springfield")?;
46//! partial.end()?;
47//!
48//! // Build the final value
49//! let value = partial.build()?;
50//! # Ok(())
51//! # }
52//! ```
53//!
54//! # Chaining Style
55//!
56//! The API supports method chaining for cleaner code:
57//!
58//! ```no_run
59//! # use facet_reflect::Partial;
60//! # use facet_core::{Shape, Facet};
61//! # fn example<T: Facet<'static>>() -> Result<(), Box<dyn std::error::Error>> {
62//! let value = Partial::alloc::<T>()?
63//!     .set_field("name", "Bob")?
64//!     .begin_field("scores")?
65//!         .set(vec![95, 87, 92])?
66//!     .end()?
67//!     .build()?;
68//! # Ok(())
69//! # }
70//! ```
71//!
72//! # Working with Collections
73//!
74//! ```no_run
75//! # use facet_reflect::Partial;
76//! # use facet_core::{Shape, Facet};
77//! # fn example() -> Result<(), Box<dyn std::error::Error>> {
78//! let mut partial = Partial::alloc::<Vec<String>>()?;
79//!
80//! // Add items to a list
81//! partial.begin_list_item()?;
82//! partial.set("first")?;
83//! partial.end()?;
84//!
85//! partial.begin_list_item()?;
86//! partial.set("second")?;
87//! partial.end()?;
88//!
89//! let vec = partial.build()?;
90//! # Ok(())
91//! # }
92//! ```
93//!
94//! # Working with Maps
95//!
96//! ```no_run
97//! # use facet_reflect::Partial;
98//! # use facet_core::{Shape, Facet};
99//! # use std::collections::HashMap;
100//! # fn example() -> Result<(), Box<dyn std::error::Error>> {
101//! let mut partial = Partial::alloc::<HashMap<String, i32>>()?;
102//!
103//! // Insert key-value pairs
104//! partial.begin_key()?;
105//! partial.set("score")?;
106//! partial.end()?;
107//! partial.begin_value()?;
108//! partial.set(100i32)?;
109//! partial.end()?;
110//!
111//! let map = partial.build()?;
112//! # Ok(())
113//! # }
114//! ```
115//!
116//! # Safety and Memory Management
117//!
118//! The `Partial` type ensures memory safety by:
119//! - Tracking initialization state of all fields
120//! - Preventing use-after-build through state tracking
121//! - Properly handling drop semantics for partially initialized values
122//! - Supporting both owned and borrowed values through lifetime parameters
123
124#[cfg(test)]
125mod tests;
126
127use alloc::boxed::Box;
128use alloc::format;
129use alloc::string::{String, ToString};
130use alloc::vec;
131
132mod iset;
133
134use crate::{Peek, ReflectError, trace};
135use facet_core::DefaultInPlaceFn;
136
137use core::marker::PhantomData;
138
139mod heap_value;
140use alloc::vec::Vec;
141pub use heap_value::*;
142
143use facet_core::{
144    Def, EnumRepr, Facet, KnownSmartPointer, PtrConst, PtrMut, PtrUninit, Shape, Type, UserType,
145    Variant,
146};
147use iset::ISet;
148
149/// State of a partial value
150#[derive(Debug, Clone, Copy, PartialEq, Eq)]
151enum PartialState {
152    /// Partial is active and can be modified
153    Active,
154    /// Partial has been successfully built and cannot be reused
155    Built,
156    /// Building failed and Partial is poisoned
157    BuildFailed,
158}
159
160/// A work-in-progress heap-allocated value
161///
162/// # Lifetimes
163///
164/// * `'facet`: The lifetime of borrowed values within the structure (or 'static if it's owned)
165/// * `'shape`: The lifetime of the Shape structure itself (often 'static)
166pub struct Partial<'facet, 'shape> {
167    /// stack of frames to keep track of deeply nested initialization
168    frames: Vec<Frame<'shape>>,
169
170    /// current state of the Partial
171    state: PartialState,
172
173    invariant: PhantomData<fn(&'facet ()) -> &'facet ()>,
174}
175
176#[derive(Clone, Copy, Debug)]
177enum MapInsertState {
178    /// Not currently inserting
179    Idle,
180    /// Pushing key
181    PushingKey {
182        /// Temporary storage for the key being built
183        key_ptr: Option<PtrUninit<'static>>,
184    },
185    /// Pushing value after key is done
186    PushingValue {
187        /// Temporary storage for the key that was built
188        key_ptr: PtrUninit<'static>,
189        /// Temporary storage for the value being built
190        value_ptr: Option<PtrUninit<'static>>,
191    },
192}
193
194#[derive(Debug)]
195enum FrameOwnership {
196    /// This frame owns the allocation and should deallocate it on drop
197    Owned,
198    /// This frame is a field pointer into a parent allocation
199    Field,
200    /// This frame's allocation is managed elsewhere (e.g., in MapInsertState)
201    ManagedElsewhere,
202}
203
204struct Frame<'shape> {
205    /// Address of the value being initialized
206    data: PtrUninit<'static>,
207
208    /// Shape of the value being initialized
209    shape: &'shape Shape<'shape>,
210
211    /// Tracks initialized fields
212    tracker: Tracker<'shape>,
213
214    /// Whether this frame owns the allocation or is just a field pointer
215    ownership: FrameOwnership,
216}
217
218enum Tracker<'shape> {
219    /// Wholly uninitialized
220    Uninit,
221
222    /// Wholly initialized
223    Init,
224
225    /// Partially initialized array
226    Array {
227        /// Track which array elements are initialized (up to 63 elements)
228        iset: ISet,
229        /// If we're pushing another frame, this is set to the array index
230        current_child: Option<usize>,
231    },
232
233    /// Partially initialized struct/tuple-struct etc.
234    Struct {
235        /// fields need to be individually tracked โ€” we only
236        /// support up to 63 fields.
237        iset: ISet,
238
239        /// if we're pushing another frame, this is set to the
240        /// index of the struct field
241        current_child: Option<usize>,
242    },
243
244    /// Smart pointer being initialized
245    SmartPointer {
246        /// Whether the inner value has been initialized
247        is_initialized: bool,
248    },
249
250    /// Partially initialized enum (but we picked a variant)
251    Enum {
252        variant: Variant<'shape>,
253        data: ISet,
254        /// If we're pushing another frame, this is set to the field index
255        current_child: Option<usize>,
256    },
257
258    /// Partially initialized list (Vec, etc.)
259    List {
260        /// The list has been initialized with capacity
261        is_initialized: bool,
262        /// If we're pushing another frame for an element
263        current_child: bool,
264    },
265
266    /// Partially initialized map (HashMap, BTreeMap, etc.)
267    Map {
268        /// The map has been initialized with capacity
269        is_initialized: bool,
270        /// State of the current insertion operation
271        insert_state: MapInsertState,
272    },
273
274    /// Option being initialized with Some(inner_value)
275    Option {
276        /// Whether we're currently building the inner value
277        building_inner: bool,
278    },
279}
280
281impl<'shape> Frame<'shape> {
282    fn new(
283        data: PtrUninit<'static>,
284        shape: &'shape Shape<'shape>,
285        ownership: FrameOwnership,
286    ) -> Self {
287        // For empty structs (structs with 0 fields), start as Init since there's nothing to initialize
288        // This includes empty tuples () which are zero-sized types with no fields to initialize
289        let tracker = match shape.ty {
290            Type::User(UserType::Struct(struct_type)) if struct_type.fields.is_empty() => {
291                Tracker::Init
292            }
293            _ => Tracker::Uninit,
294        };
295
296        Self {
297            data,
298            shape,
299            tracker,
300            ownership,
301        }
302    }
303
304    /// Returns an error if the value is not fully initialized
305    fn require_full_initialization(&self) -> Result<(), ReflectError<'shape>> {
306        match self.tracker {
307            Tracker::Uninit => Err(ReflectError::UninitializedValue { shape: self.shape }),
308            Tracker::Init => Ok(()),
309            Tracker::Array { iset, .. } => {
310                match self.shape.ty {
311                    Type::Sequence(facet_core::SequenceType::Array(array_def)) => {
312                        // Check if all array elements are initialized
313                        if (0..array_def.n).all(|idx| iset.get(idx)) {
314                            Ok(())
315                        } else {
316                            Err(ReflectError::UninitializedValue { shape: self.shape })
317                        }
318                    }
319                    _ => Err(ReflectError::UninitializedValue { shape: self.shape }),
320                }
321            }
322            Tracker::Struct { iset, .. } => {
323                if iset.all_set() {
324                    Ok(())
325                } else {
326                    // Attempt to find the first uninitialized field, if possible
327                    match self.shape.ty {
328                        Type::User(UserType::Struct(struct_type)) => {
329                            // Find index of the first bit not set
330                            let first_missing_idx =
331                                (0..struct_type.fields.len()).find(|&idx| !iset.get(idx));
332                            if let Some(missing_idx) = first_missing_idx {
333                                let field_name = struct_type.fields[missing_idx].name;
334                                Err(ReflectError::UninitializedField {
335                                    shape: self.shape,
336                                    field_name,
337                                })
338                            } else {
339                                // fallback, something went wrong
340                                Err(ReflectError::UninitializedValue { shape: self.shape })
341                            }
342                        }
343                        _ => Err(ReflectError::UninitializedValue { shape: self.shape }),
344                    }
345                }
346            }
347            Tracker::Enum { variant, data, .. } => {
348                // Check if all fields of the variant are initialized
349                let num_fields = variant.data.fields.len();
350                if num_fields == 0 {
351                    // Unit variant, always initialized
352                    Ok(())
353                } else if (0..num_fields).all(|idx| data.get(idx)) {
354                    Ok(())
355                } else {
356                    // Find the first uninitialized field
357                    let first_missing_idx = (0..num_fields).find(|&idx| !data.get(idx));
358                    if let Some(missing_idx) = first_missing_idx {
359                        let field_name = variant.data.fields[missing_idx].name;
360                        Err(ReflectError::UninitializedEnumField {
361                            shape: self.shape,
362                            field_name,
363                            variant_name: variant.name,
364                        })
365                    } else {
366                        Err(ReflectError::UninitializedValue { shape: self.shape })
367                    }
368                }
369            }
370            Tracker::SmartPointer { is_initialized } => {
371                if is_initialized {
372                    Ok(())
373                } else {
374                    Err(ReflectError::UninitializedValue { shape: self.shape })
375                }
376            }
377            Tracker::List { is_initialized, .. } => {
378                if is_initialized {
379                    Ok(())
380                } else {
381                    Err(ReflectError::UninitializedValue { shape: self.shape })
382                }
383            }
384            Tracker::Map {
385                is_initialized,
386                insert_state,
387            } => {
388                if is_initialized && matches!(insert_state, MapInsertState::Idle) {
389                    Ok(())
390                } else {
391                    Err(ReflectError::UninitializedValue { shape: self.shape })
392                }
393            }
394            Tracker::Option { building_inner } => {
395                if building_inner {
396                    Err(ReflectError::UninitializedValue { shape: self.shape })
397                } else {
398                    Ok(())
399                }
400            }
401        }
402    }
403}
404
405impl<'facet, 'shape> Partial<'facet, 'shape> {
406    /// Allocates a new Partial instance with the given shape
407    pub fn alloc_shape(shape: &'shape Shape<'shape>) -> Result<Self, ReflectError<'shape>> {
408        let data = shape
409            .allocate()
410            .map_err(|_| ReflectError::Unsized { shape })?;
411
412        Ok(Self {
413            frames: vec![Frame::new(data, shape, FrameOwnership::Owned)],
414            state: PartialState::Active,
415            invariant: PhantomData,
416        })
417    }
418
419    /// Allocates a new TypedPartial instance with the given shape and type
420    pub fn alloc<T>() -> Result<TypedPartial<'facet, 'shape, T>, ReflectError<'shape>>
421    where
422        T: Facet<'facet>,
423    {
424        Ok(TypedPartial {
425            inner: Self::alloc_shape(T::SHAPE)?,
426            phantom: PhantomData,
427        })
428    }
429
430    /// Creates a Partial from an existing pointer and shape (used for nested initialization)
431    pub fn from_ptr(data: PtrUninit<'_>, shape: &'shape Shape<'shape>) -> Self {
432        // We need to convert the lifetime, which is safe because we're storing it in a frame
433        // that will manage the lifetime correctly
434        let data_static = PtrUninit::new(data.as_mut_byte_ptr());
435        Self {
436            frames: vec![Frame::new(data_static, shape, FrameOwnership::Field)],
437            state: PartialState::Active,
438            invariant: PhantomData,
439        }
440    }
441
442    /// Require that the partial is active
443    fn require_active(&self) -> Result<(), ReflectError<'shape>> {
444        if self.state == PartialState::Active {
445            Ok(())
446        } else {
447            Err(ReflectError::InvariantViolation {
448                invariant: "Cannot use Partial after it has been built or poisoned",
449            })
450        }
451    }
452
453    /// Returns the current frame count (depth of nesting)
454    pub fn frame_count(&self) -> usize {
455        self.frames.len()
456    }
457
458    /// Sets a value wholesale into the current frame
459    pub fn set<U>(&mut self, value: U) -> Result<&mut Self, ReflectError<'shape>>
460    where
461        U: Facet<'facet>,
462    {
463        self.require_active()?;
464
465        // For conversion frames, store the value in the conversion frame itself
466        // The conversion will happen during end()
467        let ptr_const = PtrConst::new(&raw const value);
468        unsafe {
469            // Safety: We are calling set_shape with a valid shape and a valid pointer
470            self.set_shape(ptr_const, U::SHAPE)?
471        };
472
473        // Prevent the value from being dropped since we've copied it
474        core::mem::forget(value);
475        Ok(self)
476    }
477
478    /// Sets a value into the current frame by shape, for shape-based operations
479    ///
480    /// If this returns Ok, then `src_value` has been moved out of
481    ///
482    /// # Safety
483    ///
484    /// The caller must ensure that `src_value` points to a valid instance of a value
485    /// whose memory layout and type matches `src_shape`, and that this value can be
486    /// safely copied (bitwise) into the destination specified by the Partial's current frame.
487    /// No automatic drop will be performed for any existing value, so calling this on an
488    /// already-initialized destination may result in leaks or double drops if misused.
489    /// After a successful call, the ownership of the value at `src_value` is effectively moved
490    /// into the Partial (i.e., the destination), and the original value should not be used
491    /// or dropped by the caller; consider using `core::mem::forget` on the passed value.
492    /// If an error is returned, the destination remains unmodified and safe for future operations.
493    pub unsafe fn set_shape(
494        &mut self,
495        src_value: PtrConst<'_>,
496        src_shape: &'shape Shape<'shape>,
497    ) -> Result<&mut Self, ReflectError<'shape>> {
498        self.require_active()?;
499
500        let fr = self.frames.last_mut().unwrap();
501        if !fr.shape.is_shape(src_shape) {
502            let err = ReflectError::WrongShape {
503                expected: fr.shape,
504                actual: src_shape,
505            };
506            return Err(err);
507        }
508
509        if fr.shape.layout.sized_layout().is_err() {
510            return Err(ReflectError::Unsized { shape: fr.shape });
511        }
512
513        unsafe {
514            fr.data.copy_from(src_value, fr.shape).unwrap();
515        }
516        fr.tracker = Tracker::Init;
517        Ok(self)
518    }
519
520    /// Sets the current frame to its default value
521    pub fn set_default(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
522        let frame = self.frames.last().unwrap(); // Get frame to access vtable
523
524        if let Some(default_fn) = frame
525            .shape
526            .vtable
527            .sized()
528            .and_then(|v| (v.default_in_place)())
529        {
530            // Initialize with default value using set_from_function
531            // SAFETY: set_from_function handles the active check, dropping,
532            // and setting tracker. The closure passes the correct pointer type
533            // and casts to 'static which is safe within the context of calling
534            // the vtable function. The closure returns Ok(()) because the
535            // default_in_place function does not return errors.
536            self.set_from_function(move |ptr: PtrUninit<'_>| {
537                unsafe { default_fn(PtrUninit::new(ptr.as_mut_byte_ptr())) };
538                Ok(())
539            })
540        } else {
541            // Default function not available, set state and return error
542            Err(ReflectError::OperationFailed {
543                shape: frame.shape,
544                operation: "type does not implement Default",
545            })
546        }
547    }
548
549    /// Sets the current frame using a field-level default function
550    pub fn set_field_default(
551        &mut self,
552        field_default_fn: DefaultInPlaceFn,
553    ) -> Result<&mut Self, ReflectError<'shape>> {
554        // Use the field-level default function to initialize the value
555        // SAFETY: set_from_function handles the active check, dropping,
556        // and setting tracker. The closure passes the correct pointer type
557        // and casts to 'static which is safe within the context of calling
558        // the field vtable function. The closure returns Ok(()) because the
559        // default function does not return errors.
560        self.set_from_function(move |ptr: PtrUninit<'_>| {
561            unsafe { field_default_fn(PtrUninit::new(ptr.as_mut_byte_ptr())) };
562            Ok(())
563        })
564    }
565
566    /// Sets the current frame using a function that initializes the value
567    pub fn set_from_function<F>(&mut self, f: F) -> Result<&mut Self, ReflectError<'shape>>
568    where
569        F: FnOnce(PtrUninit<'_>) -> Result<(), ReflectError<'shape>>,
570    {
571        self.require_active()?;
572
573        let frame = self.frames.last_mut().unwrap();
574
575        // Check if we need to drop an existing value
576        if matches!(frame.tracker, Tracker::Init) {
577            if let Some(drop_fn) = frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)()) {
578                unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
579            }
580        }
581
582        // Don't allow overwriting when building an Option's inner value
583        if matches!(
584            frame.tracker,
585            Tracker::Option {
586                building_inner: true
587            }
588        ) {
589            return Err(ReflectError::OperationFailed {
590                shape: frame.shape,
591                operation: "Cannot overwrite while building Option inner value",
592            });
593        }
594
595        // Call the function to initialize the value
596        match f(frame.data) {
597            Ok(()) => {
598                // FIXME: what about finding out the discriminant of enums?
599                frame.tracker = Tracker::Init;
600                Ok(self)
601            }
602            Err(e) => Err(e),
603        }
604    }
605
606    /// Parses a string value into the current frame using the type's ParseFn from the vtable
607    pub fn parse_from_str(&mut self, s: &str) -> Result<&mut Self, ReflectError<'shape>> {
608        self.require_active()?;
609
610        let frame = self.frames.last_mut().unwrap();
611
612        // Check if the type has a parse function
613        let parse_fn = match frame.shape.vtable.sized().and_then(|v| (v.parse)()) {
614            Some(parse_fn) => parse_fn,
615            None => {
616                return Err(ReflectError::OperationFailed {
617                    shape: frame.shape,
618                    operation: "Type does not support parsing from string",
619                });
620            }
621        };
622
623        // Check if we need to drop an existing value
624        if matches!(frame.tracker, Tracker::Init) {
625            if let Some(drop_fn) = frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)()) {
626                unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
627            }
628        }
629
630        // Don't allow overwriting when building an Option's inner value
631        if matches!(
632            frame.tracker,
633            Tracker::Option {
634                building_inner: true
635            }
636        ) {
637            return Err(ReflectError::OperationFailed {
638                shape: frame.shape,
639                operation: "Cannot overwrite while building Option inner value",
640            });
641        }
642
643        // Parse the string value using the type's parse function
644        let result = unsafe { parse_fn(s, frame.data) };
645        match result {
646            Ok(_) => {
647                frame.tracker = Tracker::Init;
648                Ok(self)
649            }
650            Err(_parse_error) => Err(ReflectError::OperationFailed {
651                shape: frame.shape,
652                operation: "Failed to parse string value",
653            }),
654        }
655    }
656
657    /// Pushes a variant for enum initialization by name
658    pub fn select_variant_named(
659        &mut self,
660        variant_name: &str,
661    ) -> Result<&mut Self, ReflectError<'shape>> {
662        self.require_active()?;
663
664        let fr = self.frames.last_mut().unwrap();
665
666        // Check that we're dealing with an enum
667        let enum_type = match fr.shape.ty {
668            Type::User(UserType::Enum(e)) => e,
669            _ => {
670                return Err(ReflectError::OperationFailed {
671                    shape: fr.shape,
672                    operation: "push_variant_named requires an enum type",
673                });
674            }
675        };
676
677        // Find the variant with the matching name
678        let variant = match enum_type.variants.iter().find(|v| v.name == variant_name) {
679            Some(v) => v,
680            None => {
681                return Err(ReflectError::OperationFailed {
682                    shape: fr.shape,
683                    operation: "No variant found with the given name",
684                });
685            }
686        };
687
688        // Get the discriminant value
689        let discriminant = match variant.discriminant {
690            Some(d) => d,
691            None => {
692                return Err(ReflectError::OperationFailed {
693                    shape: fr.shape,
694                    operation: "Variant has no discriminant value",
695                });
696            }
697        };
698
699        // Delegate to push_variant
700        self.select_variant(discriminant)
701    }
702
703    /// Pushes a variant for enum initialization
704    pub fn select_variant(&mut self, discriminant: i64) -> Result<&mut Self, ReflectError<'shape>> {
705        self.require_active()?;
706
707        // Check all invariants early before making any changes
708        let fr = self.frames.last().unwrap();
709
710        // Check that we're dealing with an enum
711        let enum_type = match fr.shape.ty {
712            Type::User(UserType::Enum(e)) => e,
713            _ => {
714                return Err(ReflectError::WasNotA {
715                    expected: "enum",
716                    actual: fr.shape,
717                });
718            }
719        };
720
721        // Find the variant with the matching discriminant
722        let variant = match enum_type
723            .variants
724            .iter()
725            .find(|v| v.discriminant == Some(discriminant))
726        {
727            Some(v) => v,
728            None => {
729                return Err(ReflectError::OperationFailed {
730                    shape: fr.shape,
731                    operation: "No variant found with the given discriminant",
732                });
733            }
734        };
735
736        // Check enum representation early
737        match enum_type.enum_repr {
738            EnumRepr::RustNPO => {
739                return Err(ReflectError::OperationFailed {
740                    shape: fr.shape,
741                    operation: "RustNPO enums are not supported for incremental building",
742                });
743            }
744            EnumRepr::U8
745            | EnumRepr::U16
746            | EnumRepr::U32
747            | EnumRepr::U64
748            | EnumRepr::I8
749            | EnumRepr::I16
750            | EnumRepr::I32
751            | EnumRepr::I64
752            | EnumRepr::USize
753            | EnumRepr::ISize => {
754                // These are supported, continue
755            }
756            _ => {
757                return Err(ReflectError::OperationFailed {
758                    shape: fr.shape,
759                    operation: "Unknown enum representation",
760                });
761            }
762        }
763
764        // All checks passed, now we can safely make changes
765        let fr = self.frames.last_mut().unwrap();
766
767        // Write the discriminant to memory
768        unsafe {
769            match enum_type.enum_repr {
770                EnumRepr::U8 => {
771                    let ptr = fr.data.as_mut_byte_ptr();
772                    *ptr = discriminant as u8;
773                }
774                EnumRepr::U16 => {
775                    let ptr = fr.data.as_mut_byte_ptr() as *mut u16;
776                    *ptr = discriminant as u16;
777                }
778                EnumRepr::U32 => {
779                    let ptr = fr.data.as_mut_byte_ptr() as *mut u32;
780                    *ptr = discriminant as u32;
781                }
782                EnumRepr::U64 => {
783                    let ptr = fr.data.as_mut_byte_ptr() as *mut u64;
784                    *ptr = discriminant as u64;
785                }
786                EnumRepr::I8 => {
787                    let ptr = fr.data.as_mut_byte_ptr() as *mut i8;
788                    *ptr = discriminant as i8;
789                }
790                EnumRepr::I16 => {
791                    let ptr = fr.data.as_mut_byte_ptr() as *mut i16;
792                    *ptr = discriminant as i16;
793                }
794                EnumRepr::I32 => {
795                    let ptr = fr.data.as_mut_byte_ptr() as *mut i32;
796                    *ptr = discriminant as i32;
797                }
798                EnumRepr::I64 => {
799                    let ptr = fr.data.as_mut_byte_ptr() as *mut i64;
800                    *ptr = discriminant;
801                }
802                EnumRepr::USize => {
803                    let ptr = fr.data.as_mut_byte_ptr() as *mut usize;
804                    *ptr = discriminant as usize;
805                }
806                EnumRepr::ISize => {
807                    let ptr = fr.data.as_mut_byte_ptr() as *mut isize;
808                    *ptr = discriminant as isize;
809                }
810                _ => unreachable!("Already checked enum representation above"),
811            }
812        }
813
814        // Update tracker to track the variant
815        fr.tracker = Tracker::Enum {
816            variant: *variant,
817            data: ISet::new(variant.data.fields.len()),
818            current_child: None,
819        };
820
821        Ok(self)
822    }
823
824    /// Selects a field of a struct with a given name
825    pub fn begin_field(&mut self, field_name: &str) -> Result<&mut Self, ReflectError<'shape>> {
826        self.require_active()?;
827
828        let frame = self.frames.last_mut().unwrap();
829        match frame.shape.ty {
830            Type::Primitive(_) => Err(ReflectError::OperationFailed {
831                shape: frame.shape,
832                operation: "cannot select a field from a primitive type",
833            }),
834            Type::Sequence(_) => Err(ReflectError::OperationFailed {
835                shape: frame.shape,
836                operation: "cannot select a field from a sequence type",
837            }),
838            Type::User(user_type) => match user_type {
839                UserType::Struct(struct_type) => {
840                    let idx = struct_type.fields.iter().position(|f| f.name == field_name);
841                    let idx = match idx {
842                        Some(idx) => idx,
843                        None => {
844                            return Err(ReflectError::OperationFailed {
845                                shape: frame.shape,
846                                operation: "field not found",
847                            });
848                        }
849                    };
850                    self.begin_nth_field(idx)
851                }
852                UserType::Enum(_) => {
853                    // Check if we have a variant selected
854                    match &frame.tracker {
855                        Tracker::Enum { variant, .. } => {
856                            let idx = variant
857                                .data
858                                .fields
859                                .iter()
860                                .position(|f| f.name == field_name);
861                            let idx = match idx {
862                                Some(idx) => idx,
863                                None => {
864                                    return Err(ReflectError::OperationFailed {
865                                        shape: frame.shape,
866                                        operation: "field not found in current enum variant",
867                                    });
868                                }
869                            };
870                            self.begin_nth_enum_field(idx)
871                        }
872                        _ => Err(ReflectError::OperationFailed {
873                            shape: frame.shape,
874                            operation: "must call push_variant before selecting enum fields",
875                        }),
876                    }
877                }
878                UserType::Union(_) => Err(ReflectError::OperationFailed {
879                    shape: frame.shape,
880                    operation: "unions are not supported",
881                }),
882                UserType::Opaque => Err(ReflectError::OperationFailed {
883                    shape: frame.shape,
884                    operation: "opaque types cannot be reflected upon",
885                }),
886            },
887            Type::Pointer(_) => Err(ReflectError::OperationFailed {
888                shape: frame.shape,
889                operation: "cannot select a field from a pointer type",
890            }),
891            _ => todo!(),
892        }
893    }
894
895    /// Selects a variant for enum initialization, by variant index in the enum's variant list (0-based)
896    pub fn select_nth_variant(&mut self, index: usize) -> Result<&mut Self, ReflectError<'shape>> {
897        self.require_active()?;
898
899        let fr = self.frames.last().unwrap();
900
901        // Check that we're dealing with an enum
902        let enum_type = match fr.shape.ty {
903            Type::User(UserType::Enum(e)) => e,
904            _ => {
905                return Err(ReflectError::OperationFailed {
906                    shape: fr.shape,
907                    operation: "select_nth_variant requires an enum type",
908                });
909            }
910        };
911
912        if index >= enum_type.variants.len() {
913            return Err(ReflectError::OperationFailed {
914                shape: fr.shape,
915                operation: "variant index out of bounds",
916            });
917        }
918        let variant = &enum_type.variants[index];
919
920        // Get the discriminant value
921        let discriminant = match variant.discriminant {
922            Some(d) => d,
923            None => {
924                return Err(ReflectError::OperationFailed {
925                    shape: fr.shape,
926                    operation: "Variant has no discriminant value",
927                });
928            }
929        };
930
931        // Delegate to select_variant
932        self.select_variant(discriminant)
933    }
934
935    /// Selects the nth field of a struct by index
936    pub fn begin_nth_field(&mut self, idx: usize) -> Result<&mut Self, ReflectError<'shape>> {
937        self.require_active()?;
938        let frame = self.frames.last_mut().unwrap();
939        match frame.shape.ty {
940            Type::User(user_type) => match user_type {
941                UserType::Struct(struct_type) => {
942                    if idx >= struct_type.fields.len() {
943                        return Err(ReflectError::OperationFailed {
944                            shape: frame.shape,
945                            operation: "field index out of bounds",
946                        });
947                    }
948                    let field = &struct_type.fields[idx];
949
950                    match &mut frame.tracker {
951                        Tracker::Uninit => {
952                            frame.tracker = Tracker::Struct {
953                                iset: ISet::new(struct_type.fields.len()),
954                                current_child: Some(idx),
955                            }
956                        }
957                        Tracker::Struct {
958                            iset,
959                            current_child,
960                        } => {
961                            // Check if this field was already initialized
962                            if iset.get(idx) {
963                                // Drop the existing value before re-initializing
964                                let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
965                                if let Some(drop_fn) =
966                                    field.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
967                                {
968                                    unsafe { drop_fn(field_ptr) };
969                                }
970                                // Unset the bit so we can re-initialize
971                                iset.unset(idx);
972                            }
973                            *current_child = Some(idx);
974                        }
975                        _ => unreachable!(),
976                    }
977
978                    // Push a new frame for this field onto the frames stack.
979                    let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
980                    let field_shape = field.shape;
981                    self.frames
982                        .push(Frame::new(field_ptr, field_shape, FrameOwnership::Field));
983
984                    Ok(self)
985                }
986                UserType::Enum(_) => {
987                    // Check if we have a variant selected
988                    match &frame.tracker {
989                        Tracker::Enum { variant, .. } => {
990                            if idx >= variant.data.fields.len() {
991                                return Err(ReflectError::OperationFailed {
992                                    shape: frame.shape,
993                                    operation: "enum field index out of bounds",
994                                });
995                            }
996                            self.begin_nth_enum_field(idx)
997                        }
998                        _ => Err(ReflectError::OperationFailed {
999                            shape: frame.shape,
1000                            operation: "must call select_variant before selecting enum fields",
1001                        }),
1002                    }
1003                }
1004                UserType::Union(_) => Err(ReflectError::OperationFailed {
1005                    shape: frame.shape,
1006                    operation: "unions are not supported",
1007                }),
1008                UserType::Opaque => Err(ReflectError::OperationFailed {
1009                    shape: frame.shape,
1010                    operation: "opaque types cannot be reflected upon",
1011                }),
1012            },
1013            _ => Err(ReflectError::OperationFailed {
1014                shape: frame.shape,
1015                operation: "cannot select a field from this type",
1016            }),
1017        }
1018    }
1019
1020    /// Selects the nth element of an array by index
1021    pub fn begin_nth_element(&mut self, idx: usize) -> Result<&mut Self, ReflectError<'shape>> {
1022        self.require_active()?;
1023        let frame = self.frames.last_mut().unwrap();
1024        match frame.shape.ty {
1025            Type::Sequence(seq_type) => match seq_type {
1026                facet_core::SequenceType::Array(array_def) => {
1027                    if idx >= array_def.n {
1028                        return Err(ReflectError::OperationFailed {
1029                            shape: frame.shape,
1030                            operation: "array index out of bounds",
1031                        });
1032                    }
1033
1034                    if array_def.n > 63 {
1035                        return Err(ReflectError::OperationFailed {
1036                            shape: frame.shape,
1037                            operation: "arrays larger than 63 elements are not yet supported",
1038                        });
1039                    }
1040
1041                    // Ensure frame is in Array state
1042                    if matches!(frame.tracker, Tracker::Uninit) {
1043                        frame.tracker = Tracker::Array {
1044                            iset: ISet::default(),
1045                            current_child: None,
1046                        };
1047                    }
1048
1049                    match &mut frame.tracker {
1050                        Tracker::Array {
1051                            iset,
1052                            current_child,
1053                        } => {
1054                            // Calculate the offset for this array element
1055                            let element_layout = match array_def.t.layout.sized_layout() {
1056                                Ok(layout) => layout,
1057                                Err(_) => {
1058                                    return Err(ReflectError::Unsized { shape: array_def.t });
1059                                }
1060                            };
1061                            let offset = element_layout.size() * idx;
1062
1063                            // Check if this element was already initialized
1064                            if iset.get(idx) {
1065                                // Drop the existing value before re-initializing
1066                                let element_ptr = unsafe { frame.data.field_init_at(offset) };
1067                                if let Some(drop_fn) =
1068                                    array_def.t.vtable.sized().and_then(|v| (v.drop_in_place)())
1069                                {
1070                                    unsafe { drop_fn(element_ptr) };
1071                                }
1072                                // Unset the bit so we can re-initialize
1073                                iset.unset(idx);
1074                            }
1075
1076                            *current_child = Some(idx);
1077
1078                            // Create a new frame for the array element
1079                            let element_data = unsafe { frame.data.field_uninit_at(offset) };
1080                            self.frames.push(Frame::new(
1081                                element_data,
1082                                array_def.t,
1083                                FrameOwnership::Field,
1084                            ));
1085
1086                            Ok(self)
1087                        }
1088                        _ => Err(ReflectError::OperationFailed {
1089                            shape: frame.shape,
1090                            operation: "expected array tracker state",
1091                        }),
1092                    }
1093                }
1094                _ => Err(ReflectError::OperationFailed {
1095                    shape: frame.shape,
1096                    operation: "can only select elements from arrays",
1097                }),
1098            },
1099            _ => Err(ReflectError::OperationFailed {
1100                shape: frame.shape,
1101                operation: "cannot select an element from this type",
1102            }),
1103        }
1104    }
1105
1106    /// Selects the nth field of an enum variant by index
1107    pub fn begin_nth_enum_field(&mut self, idx: usize) -> Result<&mut Self, ReflectError<'shape>> {
1108        self.require_active()?;
1109        let frame = self.frames.last_mut().unwrap();
1110
1111        // Ensure we're in an enum with a variant selected
1112        let (variant, enum_type) = match (&frame.tracker, &frame.shape.ty) {
1113            (Tracker::Enum { variant, .. }, Type::User(UserType::Enum(e))) => (variant, e),
1114            _ => {
1115                return Err(ReflectError::OperationFailed {
1116                    shape: frame.shape,
1117                    operation: "push_nth_enum_field requires an enum with a variant selected",
1118                });
1119            }
1120        };
1121
1122        // Check bounds
1123        if idx >= variant.data.fields.len() {
1124            return Err(ReflectError::OperationFailed {
1125                shape: frame.shape,
1126                operation: "enum field index out of bounds",
1127            });
1128        }
1129
1130        let field = &variant.data.fields[idx];
1131
1132        // Update tracker
1133        match &mut frame.tracker {
1134            Tracker::Enum {
1135                data,
1136                current_child,
1137                ..
1138            } => {
1139                // Check if field was already initialized and drop if needed
1140                if data.get(idx) {
1141                    // Calculate the field offset, taking into account the discriminant
1142                    let _discriminant_size = match enum_type.enum_repr {
1143                        EnumRepr::U8 | EnumRepr::I8 => 1,
1144                        EnumRepr::U16 | EnumRepr::I16 => 2,
1145                        EnumRepr::U32 | EnumRepr::I32 => 4,
1146                        EnumRepr::U64 | EnumRepr::I64 => 8,
1147                        EnumRepr::USize | EnumRepr::ISize => core::mem::size_of::<usize>(),
1148                        EnumRepr::RustNPO => {
1149                            return Err(ReflectError::OperationFailed {
1150                                shape: frame.shape,
1151                                operation: "RustNPO enums are not supported",
1152                            });
1153                        }
1154                        _ => {
1155                            return Err(ReflectError::OperationFailed {
1156                                shape: frame.shape,
1157                                operation: "Unknown enum representation",
1158                            });
1159                        }
1160                    };
1161
1162                    // The field offset already includes the discriminant offset
1163                    let field_ptr = unsafe { frame.data.as_mut_byte_ptr().add(field.offset) };
1164
1165                    if let Some(drop_fn) =
1166                        field.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
1167                    {
1168                        unsafe { drop_fn(PtrMut::new(field_ptr)) };
1169                    }
1170
1171                    // Unset the bit so we can re-initialize
1172                    data.unset(idx);
1173                }
1174
1175                // Set current_child to track which field we're initializing
1176                *current_child = Some(idx);
1177            }
1178            _ => unreachable!("Already checked that we have Enum tracker"),
1179        }
1180
1181        // Extract data we need before pushing frame
1182        let field_ptr = unsafe { frame.data.as_mut_byte_ptr().add(field.offset) };
1183        let field_shape = field.shape;
1184
1185        // Push new frame for the field
1186        self.frames.push(Frame::new(
1187            PtrUninit::new(field_ptr),
1188            field_shape,
1189            FrameOwnership::Field,
1190        ));
1191
1192        Ok(self)
1193    }
1194
1195    /// Pushes a frame to initialize the inner value of a smart pointer (`Box<T>`, `Arc<T>`, etc.)
1196    pub fn begin_smart_ptr(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
1197        self.require_active()?;
1198        let frame = self.frames.last_mut().unwrap();
1199
1200        // Check that we have a SmartPointer
1201        match &frame.shape.def {
1202            Def::SmartPointer(smart_ptr_def) => {
1203                // Check for supported smart pointer types
1204                match smart_ptr_def.known {
1205                    Some(KnownSmartPointer::Box) | Some(KnownSmartPointer::Arc) => {
1206                        // Supported types, continue
1207                    }
1208                    _ => {
1209                        return Err(ReflectError::OperationFailed {
1210                            shape: frame.shape,
1211                            operation: "only Box and Arc smart pointers are currently supported",
1212                        });
1213                    }
1214                }
1215
1216                // Get the pointee shape
1217                let pointee_shape = match smart_ptr_def.pointee() {
1218                    Some(shape) => shape,
1219                    None => {
1220                        return Err(ReflectError::OperationFailed {
1221                            shape: frame.shape,
1222                            operation: "Box must have a pointee shape",
1223                        });
1224                    }
1225                };
1226
1227                // Update tracker to SmartPointer state
1228                if matches!(frame.tracker, Tracker::Uninit) {
1229                    frame.tracker = Tracker::SmartPointer {
1230                        is_initialized: false,
1231                    };
1232                }
1233
1234                // Allocate space for the inner value
1235                let inner_layout = match pointee_shape.layout.sized_layout() {
1236                    Ok(layout) => layout,
1237                    Err(_) => {
1238                        return Err(ReflectError::Unsized {
1239                            shape: pointee_shape,
1240                        });
1241                    }
1242                };
1243                let inner_ptr: *mut u8 = unsafe { alloc::alloc::alloc(inner_layout) };
1244
1245                if inner_ptr.is_null() {
1246                    return Err(ReflectError::OperationFailed {
1247                        shape: frame.shape,
1248                        operation: "failed to allocate memory for Box inner value",
1249                    });
1250                }
1251
1252                // Push a new frame for the inner value
1253                self.frames.push(Frame::new(
1254                    PtrUninit::new(inner_ptr),
1255                    pointee_shape,
1256                    FrameOwnership::Owned,
1257                ));
1258
1259                Ok(self)
1260            }
1261            _ => Err(ReflectError::OperationFailed {
1262                shape: frame.shape,
1263                operation: "push_smart_ptr can only be called on compatible types",
1264            }),
1265        }
1266    }
1267
1268    /// Begins a pushback operation for a list (Vec, etc.)
1269    /// This initializes the list with default capacity and allows pushing elements
1270    pub fn begin_list(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
1271        self.require_active()?;
1272        let frame = self.frames.last_mut().unwrap();
1273
1274        // Check that we have a List
1275        let list_def = match &frame.shape.def {
1276            Def::List(list_def) => list_def,
1277            _ => {
1278                return Err(ReflectError::OperationFailed {
1279                    shape: frame.shape,
1280                    operation: "begin_pushback can only be called on List types",
1281                });
1282            }
1283        };
1284
1285        // Check that we have init_in_place_with_capacity function
1286        let init_fn = match list_def.vtable.init_in_place_with_capacity {
1287            Some(f) => f,
1288            None => {
1289                return Err(ReflectError::OperationFailed {
1290                    shape: frame.shape,
1291                    operation: "list type does not support initialization with capacity",
1292                });
1293            }
1294        };
1295
1296        // Initialize the list with default capacity (0)
1297        unsafe {
1298            init_fn(frame.data, 0);
1299        }
1300
1301        // Update tracker to List state
1302        frame.tracker = Tracker::List {
1303            is_initialized: true,
1304            current_child: false,
1305        };
1306
1307        Ok(self)
1308    }
1309
1310    /// Begins a map initialization operation
1311    /// This initializes the map with default capacity and allows inserting key-value pairs
1312    pub fn begin_map(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
1313        self.require_active()?;
1314        let frame = self.frames.last_mut().unwrap();
1315
1316        // Check that we have a Map
1317        let map_def = match &frame.shape.def {
1318            Def::Map(map_def) => map_def,
1319            _ => {
1320                return Err(ReflectError::OperationFailed {
1321                    shape: frame.shape,
1322                    operation: "begin_map can only be called on Map types",
1323                });
1324            }
1325        };
1326
1327        // Check that we have init_in_place_with_capacity function
1328        let init_fn = map_def.vtable.init_in_place_with_capacity_fn;
1329
1330        // Initialize the map with default capacity (0)
1331        unsafe {
1332            init_fn(frame.data, 0);
1333        }
1334
1335        // Update tracker to Map state
1336        frame.tracker = Tracker::Map {
1337            is_initialized: true,
1338            insert_state: MapInsertState::Idle,
1339        };
1340
1341        Ok(self)
1342    }
1343
1344    /// Pushes a frame for the map key
1345    /// Automatically starts a new insert if we're idle
1346    pub fn begin_key(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
1347        self.require_active()?;
1348        let frame = self.frames.last_mut().unwrap();
1349
1350        // Check that we have a Map and set up for key insertion
1351        let map_def = match (&frame.shape.def, &mut frame.tracker) {
1352            (
1353                Def::Map(map_def),
1354                Tracker::Map {
1355                    is_initialized: true,
1356                    insert_state,
1357                },
1358            ) => {
1359                match insert_state {
1360                    MapInsertState::Idle => {
1361                        // Start a new insert automatically
1362                        *insert_state = MapInsertState::PushingKey { key_ptr: None };
1363                    }
1364                    MapInsertState::PushingKey { key_ptr } => {
1365                        if key_ptr.is_some() {
1366                            return Err(ReflectError::OperationFailed {
1367                                shape: frame.shape,
1368                                operation: "already pushing a key, call end() first",
1369                            });
1370                        }
1371                    }
1372                    _ => {
1373                        return Err(ReflectError::OperationFailed {
1374                            shape: frame.shape,
1375                            operation: "must complete current operation before begin_key()",
1376                        });
1377                    }
1378                }
1379                map_def
1380            }
1381            _ => {
1382                return Err(ReflectError::OperationFailed {
1383                    shape: frame.shape,
1384                    operation: "must call begin_map() before begin_key()",
1385                });
1386            }
1387        };
1388
1389        // Get the key shape
1390        let key_shape = map_def.k();
1391
1392        // Allocate space for the key
1393        let key_layout = match key_shape.layout.sized_layout() {
1394            Ok(layout) => layout,
1395            Err(_) => {
1396                return Err(ReflectError::Unsized { shape: key_shape });
1397            }
1398        };
1399        let key_ptr_raw: *mut u8 = unsafe { alloc::alloc::alloc(key_layout) };
1400
1401        if key_ptr_raw.is_null() {
1402            return Err(ReflectError::OperationFailed {
1403                shape: frame.shape,
1404                operation: "failed to allocate memory for map key",
1405            });
1406        }
1407
1408        // Store the key pointer in the insert state
1409        match &mut frame.tracker {
1410            Tracker::Map {
1411                insert_state: MapInsertState::PushingKey { key_ptr: kp },
1412                ..
1413            } => {
1414                *kp = Some(PtrUninit::new(key_ptr_raw));
1415            }
1416            _ => unreachable!(),
1417        }
1418
1419        // Push a new frame for the key
1420        self.frames.push(Frame::new(
1421            PtrUninit::new(key_ptr_raw),
1422            key_shape,
1423            FrameOwnership::ManagedElsewhere, // Ownership tracked in MapInsertState
1424        ));
1425
1426        Ok(self)
1427    }
1428
1429    /// Pushes a frame for the map value
1430    /// Must be called after the key has been set and popped
1431    pub fn begin_value(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
1432        self.require_active()?;
1433        let frame = self.frames.last_mut().unwrap();
1434
1435        // Check that we have a Map in PushingValue state
1436        let map_def = match (&frame.shape.def, &mut frame.tracker) {
1437            (
1438                Def::Map(map_def),
1439                Tracker::Map {
1440                    insert_state: MapInsertState::PushingValue { value_ptr, .. },
1441                    ..
1442                },
1443            ) => {
1444                if value_ptr.is_some() {
1445                    return Err(ReflectError::OperationFailed {
1446                        shape: frame.shape,
1447                        operation: "already pushing a value, call pop() first",
1448                    });
1449                }
1450                map_def
1451            }
1452            _ => {
1453                return Err(ReflectError::OperationFailed {
1454                    shape: frame.shape,
1455                    operation: "must complete key before push_value()",
1456                });
1457            }
1458        };
1459
1460        // Get the value shape
1461        let value_shape = map_def.v();
1462
1463        // Allocate space for the value
1464        let value_layout = match value_shape.layout.sized_layout() {
1465            Ok(layout) => layout,
1466            Err(_) => {
1467                return Err(ReflectError::Unsized { shape: value_shape });
1468            }
1469        };
1470        let value_ptr_raw: *mut u8 = unsafe { alloc::alloc::alloc(value_layout) };
1471
1472        if value_ptr_raw.is_null() {
1473            return Err(ReflectError::OperationFailed {
1474                shape: frame.shape,
1475                operation: "failed to allocate memory for map value",
1476            });
1477        }
1478
1479        // Store the value pointer in the insert state
1480        match &mut frame.tracker {
1481            Tracker::Map {
1482                insert_state: MapInsertState::PushingValue { value_ptr: vp, .. },
1483                ..
1484            } => {
1485                *vp = Some(PtrUninit::new(value_ptr_raw));
1486            }
1487            _ => unreachable!(),
1488        }
1489
1490        // Push a new frame for the value
1491        self.frames.push(Frame::new(
1492            PtrUninit::new(value_ptr_raw),
1493            value_shape,
1494            FrameOwnership::ManagedElsewhere, // Ownership tracked in MapInsertState
1495        ));
1496
1497        Ok(self)
1498    }
1499
1500    /// Pushes an element to the list
1501    /// The element should be set using `set()` or similar methods, then `pop()` to complete
1502    pub fn begin_list_item(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
1503        self.require_active()?;
1504        let frame = self.frames.last_mut().unwrap();
1505
1506        // Check that we have a List that's been initialized
1507        let list_def = match &frame.shape.def {
1508            Def::List(list_def) => list_def,
1509            _ => {
1510                return Err(ReflectError::OperationFailed {
1511                    shape: frame.shape,
1512                    operation: "push can only be called on List types",
1513                });
1514            }
1515        };
1516
1517        // Verify the tracker is in List state and initialized
1518        match &mut frame.tracker {
1519            Tracker::List {
1520                is_initialized: true,
1521                current_child,
1522            } => {
1523                if *current_child {
1524                    return Err(ReflectError::OperationFailed {
1525                        shape: frame.shape,
1526                        operation: "already pushing an element, call pop() first",
1527                    });
1528                }
1529                *current_child = true;
1530            }
1531            _ => {
1532                return Err(ReflectError::OperationFailed {
1533                    shape: frame.shape,
1534                    operation: "must call begin_pushback() before push()",
1535                });
1536            }
1537        }
1538
1539        // Get the element shape
1540        let element_shape = list_def.t();
1541
1542        // Allocate space for the new element
1543        let element_layout = match element_shape.layout.sized_layout() {
1544            Ok(layout) => layout,
1545            Err(_) => {
1546                return Err(ReflectError::Unsized {
1547                    shape: element_shape,
1548                });
1549            }
1550        };
1551        let element_ptr: *mut u8 = unsafe { alloc::alloc::alloc(element_layout) };
1552
1553        if element_ptr.is_null() {
1554            return Err(ReflectError::OperationFailed {
1555                shape: frame.shape,
1556                operation: "failed to allocate memory for list element",
1557            });
1558        }
1559
1560        // Push a new frame for the element
1561        self.frames.push(Frame::new(
1562            PtrUninit::new(element_ptr),
1563            element_shape,
1564            FrameOwnership::Owned,
1565        ));
1566
1567        Ok(self)
1568    }
1569
1570    /// Pops the current frame off the stack, indicating we're done initializing the current field.
1571    pub fn end(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
1572        self.require_active()?;
1573        if self.frames.len() <= 1 {
1574            // Never pop the last/root frame.
1575            return Err(ReflectError::InvariantViolation {
1576                invariant: "Partial::end() called with only one frame on the stack",
1577            });
1578        }
1579
1580        // Require that the top frame is fully initialized before popping.
1581        {
1582            let frame = self.frames.last().unwrap();
1583            trace!(
1584                "end(): Checking full initialization for frame with shape {}",
1585                frame.shape
1586            );
1587            frame.require_full_initialization()?
1588        }
1589
1590        // Pop the frame and save its data pointer for SmartPointer handling
1591        let popped_frame = self.frames.pop().unwrap();
1592        let _is_conversion = false;
1593        trace!(
1594            "end(): Popped frame with shape {}, is_conversion={}",
1595            popped_frame.shape, _is_conversion
1596        );
1597
1598        // Update parent frame's tracking when popping from a child
1599        let parent_frame = self.frames.last_mut().unwrap();
1600
1601        // Check if we need to do a conversion - this happens when:
1602        // 1. The parent frame has an inner type that matches the popped frame's shape
1603        // 2. The parent frame has try_from
1604        // 3. The parent frame is not yet initialized
1605        let needs_conversion = matches!(parent_frame.tracker, Tracker::Uninit)
1606            && parent_frame.shape.inner.is_some()
1607            && parent_frame.shape.inner.unwrap()() == popped_frame.shape
1608            && parent_frame
1609                .shape
1610                .vtable
1611                .sized()
1612                .and_then(|v| (v.try_from)())
1613                .is_some();
1614
1615        if needs_conversion {
1616            trace!(
1617                "Detected implicit conversion needed from {} to {}",
1618                popped_frame.shape, parent_frame.shape
1619            );
1620            // Perform the conversion
1621            if let Some(try_from_fn) = parent_frame
1622                .shape
1623                .vtable
1624                .sized()
1625                .and_then(|v| (v.try_from)())
1626            {
1627                let inner_ptr = unsafe { popped_frame.data.assume_init().as_const() };
1628                let inner_shape = popped_frame.shape;
1629
1630                trace!("Converting from {} to {}", inner_shape, parent_frame.shape);
1631                let result = unsafe { try_from_fn(inner_ptr, inner_shape, parent_frame.data) };
1632
1633                if let Err(e) = result {
1634                    trace!("Conversion failed: {:?}", e);
1635
1636                    // Deallocate the inner value's memory since conversion failed
1637                    if let FrameOwnership::Owned = popped_frame.ownership {
1638                        if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
1639                            if layout.size() > 0 {
1640                                trace!(
1641                                    "Deallocating conversion frame memory after failure: size={}, align={}",
1642                                    layout.size(),
1643                                    layout.align()
1644                                );
1645                                unsafe {
1646                                    alloc::alloc::dealloc(
1647                                        popped_frame.data.as_mut_byte_ptr(),
1648                                        layout,
1649                                    );
1650                                }
1651                            }
1652                        }
1653                    }
1654
1655                    return Err(ReflectError::TryFromError {
1656                        src_shape: inner_shape,
1657                        dst_shape: parent_frame.shape,
1658                        inner: e,
1659                    });
1660                }
1661
1662                trace!("Conversion succeeded, marking parent as initialized");
1663                parent_frame.tracker = Tracker::Init;
1664
1665                // Deallocate the inner value's memory since try_from consumed it
1666                if let FrameOwnership::Owned = popped_frame.ownership {
1667                    if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
1668                        if layout.size() > 0 {
1669                            trace!(
1670                                "Deallocating conversion frame memory: size={}, align={}",
1671                                layout.size(),
1672                                layout.align()
1673                            );
1674                            unsafe {
1675                                alloc::alloc::dealloc(popped_frame.data.as_mut_byte_ptr(), layout);
1676                            }
1677                        }
1678                    }
1679                }
1680
1681                return Ok(self);
1682            }
1683        }
1684
1685        match &mut parent_frame.tracker {
1686            Tracker::Struct {
1687                iset,
1688                current_child,
1689            } => {
1690                if let Some(idx) = *current_child {
1691                    iset.set(idx);
1692                    *current_child = None;
1693                }
1694            }
1695            Tracker::Array {
1696                iset,
1697                current_child,
1698            } => {
1699                if let Some(idx) = *current_child {
1700                    iset.set(idx);
1701                    *current_child = None;
1702                }
1703            }
1704            Tracker::SmartPointer { is_initialized } => {
1705                // We just popped the inner value frame, so now we need to create the Box
1706                if let Def::SmartPointer(smart_ptr_def) = parent_frame.shape.def {
1707                    if let Some(new_into_fn) = smart_ptr_def.vtable.new_into_fn {
1708                        // The child frame contained the inner value
1709                        let inner_ptr = PtrMut::new(popped_frame.data.as_mut_byte_ptr());
1710
1711                        // Use new_into_fn to create the Box
1712                        unsafe {
1713                            new_into_fn(parent_frame.data, inner_ptr);
1714                        }
1715
1716                        // Deallocate the inner value's memory since new_into_fn moved it
1717                        if let FrameOwnership::Owned = popped_frame.ownership {
1718                            if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
1719                                if layout.size() > 0 {
1720                                    unsafe {
1721                                        alloc::alloc::dealloc(
1722                                            popped_frame.data.as_mut_byte_ptr(),
1723                                            layout,
1724                                        );
1725                                    }
1726                                }
1727                            }
1728                        }
1729
1730                        *is_initialized = true;
1731                    } else {
1732                        return Err(ReflectError::OperationFailed {
1733                            shape: parent_frame.shape,
1734                            operation: "SmartPointer missing new_into_fn",
1735                        });
1736                    }
1737                }
1738            }
1739            Tracker::Enum {
1740                data,
1741                current_child,
1742                ..
1743            } => {
1744                if let Some(idx) = *current_child {
1745                    data.set(idx);
1746                    *current_child = None;
1747                }
1748            }
1749            Tracker::List {
1750                is_initialized: true,
1751                current_child,
1752            } => {
1753                if *current_child {
1754                    // We just popped an element frame, now push it to the list
1755                    if let Def::List(list_def) = parent_frame.shape.def {
1756                        if let Some(push_fn) = list_def.vtable.push {
1757                            // The child frame contained the element value
1758                            let element_ptr = PtrMut::new(popped_frame.data.as_mut_byte_ptr());
1759
1760                            // Use push to add element to the list
1761                            unsafe {
1762                                push_fn(
1763                                    PtrMut::new(parent_frame.data.as_mut_byte_ptr()),
1764                                    element_ptr,
1765                                );
1766                            }
1767
1768                            // Deallocate the element's memory since push moved it
1769                            if let FrameOwnership::Owned = popped_frame.ownership {
1770                                if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
1771                                    if layout.size() > 0 {
1772                                        unsafe {
1773                                            alloc::alloc::dealloc(
1774                                                popped_frame.data.as_mut_byte_ptr(),
1775                                                layout,
1776                                            );
1777                                        }
1778                                    }
1779                                }
1780                            }
1781
1782                            *current_child = false;
1783                        } else {
1784                            return Err(ReflectError::OperationFailed {
1785                                shape: parent_frame.shape,
1786                                operation: "List missing push function",
1787                            });
1788                        }
1789                    }
1790                }
1791            }
1792            Tracker::Map {
1793                is_initialized: true,
1794                insert_state,
1795            } => {
1796                match insert_state {
1797                    MapInsertState::PushingKey { key_ptr } => {
1798                        // We just popped the key frame
1799                        if let Some(key_ptr) = key_ptr {
1800                            // Transition to PushingValue state
1801                            *insert_state = MapInsertState::PushingValue {
1802                                key_ptr: *key_ptr,
1803                                value_ptr: None,
1804                            };
1805                        }
1806                    }
1807                    MapInsertState::PushingValue { key_ptr, value_ptr } => {
1808                        // We just popped the value frame, now insert the pair
1809                        if let (Some(value_ptr), Def::Map(map_def)) =
1810                            (value_ptr, parent_frame.shape.def)
1811                        {
1812                            let insert_fn = map_def.vtable.insert_fn;
1813
1814                            // Use insert to add key-value pair to the map
1815                            unsafe {
1816                                insert_fn(
1817                                    PtrMut::new(parent_frame.data.as_mut_byte_ptr()),
1818                                    PtrMut::new(key_ptr.as_mut_byte_ptr()),
1819                                    PtrMut::new(value_ptr.as_mut_byte_ptr()),
1820                                );
1821                            }
1822
1823                            // Note: We don't deallocate the key and value memory here.
1824                            // The insert function has semantically moved the values into the map,
1825                            // but we still need to deallocate the temporary buffers.
1826                            // However, since we don't have frames for them anymore (they were popped),
1827                            // we need to handle deallocation here.
1828                            if let Ok(key_shape) = map_def.k().layout.sized_layout() {
1829                                if key_shape.size() > 0 {
1830                                    unsafe {
1831                                        alloc::alloc::dealloc(key_ptr.as_mut_byte_ptr(), key_shape);
1832                                    }
1833                                }
1834                            }
1835                            if let Ok(value_shape) = map_def.v().layout.sized_layout() {
1836                                if value_shape.size() > 0 {
1837                                    unsafe {
1838                                        alloc::alloc::dealloc(
1839                                            value_ptr.as_mut_byte_ptr(),
1840                                            value_shape,
1841                                        );
1842                                    }
1843                                }
1844                            }
1845
1846                            // Reset to idle state
1847                            *insert_state = MapInsertState::Idle;
1848                        }
1849                    }
1850                    MapInsertState::Idle => {
1851                        // Nothing to do
1852                    }
1853                }
1854            }
1855            Tracker::Option { building_inner } => {
1856                // We just popped the inner value frame for an Option's Some variant
1857                if *building_inner {
1858                    if let Def::Option(option_def) = parent_frame.shape.def {
1859                        // Use the Option vtable to initialize Some(inner_value)
1860                        let init_some_fn = option_def.vtable.init_some_fn;
1861
1862                        // The popped frame contains the inner value
1863                        let inner_value_ptr = unsafe { popped_frame.data.assume_init().as_const() };
1864
1865                        // Initialize the Option as Some(inner_value)
1866                        unsafe {
1867                            init_some_fn(parent_frame.data, inner_value_ptr);
1868                        }
1869
1870                        // Deallocate the inner value's memory since init_some_fn moved it
1871                        if let FrameOwnership::Owned = popped_frame.ownership {
1872                            if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
1873                                if layout.size() > 0 {
1874                                    unsafe {
1875                                        alloc::alloc::dealloc(
1876                                            popped_frame.data.as_mut_byte_ptr(),
1877                                            layout,
1878                                        );
1879                                    }
1880                                }
1881                            }
1882                        }
1883
1884                        // Mark that we're no longer building the inner value
1885                        *building_inner = false;
1886                    } else {
1887                        return Err(ReflectError::OperationFailed {
1888                            shape: parent_frame.shape,
1889                            operation: "Option frame without Option definition",
1890                        });
1891                    }
1892                }
1893            }
1894            _ => {}
1895        }
1896
1897        Ok(self)
1898    }
1899
1900    /// Builds the value
1901    pub fn build(&mut self) -> Result<HeapValue<'facet, 'shape>, ReflectError<'shape>> {
1902        self.require_active()?;
1903        if self.frames.len() != 1 {
1904            self.state = PartialState::BuildFailed;
1905            return Err(ReflectError::InvariantViolation {
1906                invariant: "Partial::build() expects a single frame โ€” pop until that's the case",
1907            });
1908        }
1909
1910        let frame = self.frames.pop().unwrap();
1911
1912        // Check initialization before proceeding
1913        if let Err(e) = frame.require_full_initialization() {
1914            // Put the frame back so Drop can handle cleanup properly
1915            self.frames.push(frame);
1916            self.state = PartialState::BuildFailed;
1917            return Err(e);
1918        }
1919
1920        // Check invariants if present
1921        if let Some(invariants_fn) = frame.shape.vtable.sized().and_then(|v| (v.invariants)()) {
1922            // Safety: The value is fully initialized at this point (we just checked with require_full_initialization)
1923            let value_ptr = unsafe { frame.data.assume_init().as_const() };
1924            let invariants_ok = unsafe { invariants_fn(value_ptr) };
1925
1926            if !invariants_ok {
1927                // Put the frame back so Drop can handle cleanup properly
1928                self.frames.push(frame);
1929                self.state = PartialState::BuildFailed;
1930                return Err(ReflectError::InvariantViolation {
1931                    invariant: "Type invariants check failed",
1932                });
1933            }
1934        }
1935
1936        // Mark as built to prevent reuse
1937        self.state = PartialState::Built;
1938
1939        match frame
1940            .shape
1941            .layout
1942            .sized_layout()
1943            .map_err(|_| ReflectError::Unsized { shape: frame.shape })
1944        {
1945            Ok(layout) => Ok(HeapValue {
1946                guard: Some(Guard {
1947                    ptr: frame.data.as_mut_byte_ptr(),
1948                    layout,
1949                }),
1950                shape: frame.shape,
1951                phantom: PhantomData,
1952            }),
1953            Err(e) => {
1954                // Put the frame back for proper cleanup
1955                self.frames.push(frame);
1956                self.state = PartialState::BuildFailed;
1957                Err(e)
1958            }
1959        }
1960    }
1961
1962    /// Returns a human-readable path representing the current traversal in the builder,
1963    /// e.g., `RootStruct.fieldName[index].subfield`.
1964    pub fn path(&self) -> String {
1965        let mut out = String::new();
1966
1967        let mut path_components = Vec::new();
1968        // The stack of enum/struct/sequence names currently in context.
1969        // Start from root and build upwards.
1970        for (i, frame) in self.frames.iter().enumerate() {
1971            match frame.shape.ty {
1972                Type::User(user_type) => match user_type {
1973                    UserType::Struct(struct_type) => {
1974                        // Try to get currently active field index
1975                        let mut field_str = None;
1976                        if let Tracker::Struct {
1977                            current_child: Some(idx),
1978                            ..
1979                        } = &frame.tracker
1980                        {
1981                            if let Some(field) = struct_type.fields.get(*idx) {
1982                                field_str = Some(field.name);
1983                            }
1984                        }
1985                        if i == 0 {
1986                            // Use Display for the root struct shape
1987                            path_components.push(format!("{}", frame.shape));
1988                        }
1989                        if let Some(field_name) = field_str {
1990                            path_components.push(format!(".{}", field_name));
1991                        }
1992                    }
1993                    UserType::Enum(_enum_type) => {
1994                        // Try to get currently active variant and field
1995                        if let Tracker::Enum {
1996                            variant,
1997                            current_child,
1998                            ..
1999                        } = &frame.tracker
2000                        {
2001                            if i == 0 {
2002                                // Use Display for the root enum shape
2003                                path_components.push(format!("{}", frame.shape));
2004                            }
2005                            path_components.push(format!("::{}", variant.name));
2006                            if let Some(idx) = *current_child {
2007                                if let Some(field) = variant.data.fields.get(idx) {
2008                                    path_components.push(format!(".{}", field.name));
2009                                }
2010                            }
2011                        } else if i == 0 {
2012                            // just the enum display
2013                            path_components.push(format!("{}", frame.shape));
2014                        }
2015                    }
2016                    UserType::Union(_union_type) => {
2017                        path_components.push(format!("{}", frame.shape));
2018                    }
2019                    UserType::Opaque => {
2020                        path_components.push("<opaque>".to_string());
2021                    }
2022                },
2023                Type::Sequence(seq_type) => match seq_type {
2024                    facet_core::SequenceType::Array(_array_def) => {
2025                        // Try to show current element index
2026                        if let Tracker::Array {
2027                            current_child: Some(idx),
2028                            ..
2029                        } = &frame.tracker
2030                        {
2031                            path_components.push(format!("[{}]", idx));
2032                        }
2033                    }
2034                    // You can add more for Slice, Vec, etc., if applicable
2035                    _ => {
2036                        // just indicate "[]" for sequence
2037                        path_components.push("[]".to_string());
2038                    }
2039                },
2040                Type::Pointer(_) => {
2041                    // Indicate deref
2042                    path_components.push("*".to_string());
2043                }
2044                _ => {
2045                    // No structural path
2046                }
2047            }
2048        }
2049        // Merge the path_components into a single string
2050        for component in path_components {
2051            out.push_str(&component);
2052        }
2053        out
2054    }
2055
2056    /// Returns the shape of the current frame.
2057    pub fn shape(&self) -> &'shape Shape<'shape> {
2058        self.frames
2059            .last()
2060            .expect("Partial always has at least one frame")
2061            .shape
2062    }
2063
2064    /// Returns the innermost shape (alias for shape(), for compatibility)
2065    pub fn innermost_shape(&self) -> &'shape Shape<'shape> {
2066        self.shape()
2067    }
2068
2069    /// Check if a struct field at the given index has been set
2070    pub fn is_field_set(&self, index: usize) -> Result<bool, ReflectError<'shape>> {
2071        let frame = self.frames.last().ok_or(ReflectError::NoActiveFrame)?;
2072
2073        match &frame.tracker {
2074            Tracker::Uninit => Ok(false),
2075            Tracker::Init => Ok(true),
2076            Tracker::Struct { iset, .. } => Ok(iset.get(index)),
2077            Tracker::Enum { data, .. } => {
2078                // Check if the field is already marked as set
2079                if data.get(index) {
2080                    return Ok(true);
2081                }
2082
2083                // For enum variant fields that are empty structs, they are always initialized
2084                if let Tracker::Enum { variant, .. } = &frame.tracker {
2085                    if let Some(field) = variant.data.fields.get(index) {
2086                        if let Type::User(UserType::Struct(field_struct)) = field.shape.ty {
2087                            if field_struct.fields.is_empty() {
2088                                return Ok(true);
2089                            }
2090                        }
2091                    }
2092                }
2093
2094                Ok(false)
2095            }
2096            Tracker::Option { building_inner } => {
2097                // For Options, index 0 represents the inner value
2098                if index == 0 {
2099                    Ok(!building_inner)
2100                } else {
2101                    Err(ReflectError::InvalidOperation {
2102                        operation: "is_field_set",
2103                        reason: "Option only has one field (index 0)",
2104                    })
2105                }
2106            }
2107            _ => Err(ReflectError::InvalidOperation {
2108                operation: "is_field_set",
2109                reason: "Current frame is not a struct, enum variant, or option",
2110            }),
2111        }
2112    }
2113
2114    /// Find the index of a field by name in the current struct
2115    pub fn field_index(&self, field_name: &str) -> Option<usize> {
2116        let frame = self.frames.last()?;
2117
2118        match frame.shape.ty {
2119            Type::User(UserType::Struct(struct_def)) => {
2120                struct_def.fields.iter().position(|f| f.name == field_name)
2121            }
2122            Type::User(UserType::Enum(_)) => {
2123                // If we're in an enum variant, check its fields
2124                if let Tracker::Enum { variant, .. } = &frame.tracker {
2125                    variant
2126                        .data
2127                        .fields
2128                        .iter()
2129                        .position(|f| f.name == field_name)
2130                } else {
2131                    None
2132                }
2133            }
2134            _ => None,
2135        }
2136    }
2137
2138    /// Get the currently selected variant for an enum
2139    pub fn selected_variant(&self) -> Option<Variant<'shape>> {
2140        let frame = self.frames.last()?;
2141
2142        match &frame.tracker {
2143            Tracker::Enum { variant, .. } => Some(*variant),
2144            _ => None,
2145        }
2146    }
2147
2148    /// Find a variant by name in the current enum
2149    pub fn find_variant(&self, variant_name: &str) -> Option<(usize, &'shape Variant<'shape>)> {
2150        let frame = self.frames.last()?;
2151
2152        if let Type::User(UserType::Enum(enum_def)) = frame.shape.ty {
2153            enum_def
2154                .variants
2155                .iter()
2156                .enumerate()
2157                .find(|(_, v)| v.name == variant_name)
2158        } else {
2159            None
2160        }
2161    }
2162
2163    /// Begin building the Some variant of an Option
2164    pub fn begin_some(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2165        self.require_active()?;
2166        let frame = self.frames.last_mut().unwrap();
2167
2168        // Verify we're working with an Option
2169        let option_def = match frame.shape.def {
2170            Def::Option(def) => def,
2171            _ => {
2172                return Err(ReflectError::WasNotA {
2173                    expected: "Option",
2174                    actual: frame.shape,
2175                });
2176            }
2177        };
2178
2179        // Initialize the tracker for Option building
2180        if matches!(frame.tracker, Tracker::Uninit) {
2181            frame.tracker = Tracker::Option {
2182                building_inner: true,
2183            };
2184        }
2185
2186        // Get the inner type shape
2187        let inner_shape = option_def.t;
2188
2189        // Allocate memory for the inner value
2190        let inner_layout = inner_shape
2191            .layout
2192            .sized_layout()
2193            .map_err(|_| ReflectError::Unsized { shape: inner_shape })?;
2194
2195        let inner_data = if inner_layout.size() == 0 {
2196            // For ZST, use a non-null but unallocated pointer
2197            PtrUninit::new(core::ptr::NonNull::<u8>::dangling().as_ptr())
2198        } else {
2199            // Allocate memory for the inner value
2200            let ptr = unsafe { alloc::alloc::alloc(inner_layout) };
2201            if ptr.is_null() {
2202                alloc::alloc::handle_alloc_error(inner_layout);
2203            }
2204            PtrUninit::new(ptr)
2205        };
2206
2207        // Create a new frame for the inner value
2208        let inner_frame = Frame::new(inner_data, inner_shape, FrameOwnership::Owned);
2209        self.frames.push(inner_frame);
2210
2211        Ok(self)
2212    }
2213
2214    /// Begin building the inner value of a wrapper type
2215    pub fn begin_inner(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2216        self.require_active()?;
2217
2218        // Get the inner shape and check for try_from
2219        let (inner_shape, has_try_from, parent_shape) = {
2220            let frame = self.frames.last().unwrap();
2221            if let Some(inner_fn) = frame.shape.inner {
2222                let inner_shape = inner_fn();
2223                let has_try_from = frame
2224                    .shape
2225                    .vtable
2226                    .sized()
2227                    .and_then(|v| (v.try_from)())
2228                    .is_some();
2229                (Some(inner_shape), has_try_from, frame.shape)
2230            } else {
2231                (None, false, frame.shape)
2232            }
2233        };
2234
2235        if let Some(inner_shape) = inner_shape {
2236            if has_try_from {
2237                // Create a conversion frame with the inner shape
2238
2239                // For conversion frames, we leave the parent tracker unchanged
2240                // This allows automatic conversion detection to work properly
2241
2242                // Allocate memory for the inner value (conversion source)
2243                let inner_layout = inner_shape
2244                    .layout
2245                    .sized_layout()
2246                    .map_err(|_| ReflectError::Unsized { shape: inner_shape })?;
2247
2248                let inner_data = if inner_layout.size() == 0 {
2249                    // For ZST, use a non-null but unallocated pointer
2250                    PtrUninit::new(core::ptr::NonNull::<u8>::dangling().as_ptr())
2251                } else {
2252                    // Allocate memory for the inner value
2253                    let ptr = unsafe { alloc::alloc::alloc(inner_layout) };
2254                    if ptr.is_null() {
2255                        alloc::alloc::handle_alloc_error(inner_layout);
2256                    }
2257                    PtrUninit::new(ptr)
2258                };
2259
2260                // For conversion frames, we create a frame directly with the inner shape
2261                // This allows setting values of the inner type which will be converted
2262                // The automatic conversion detection in end() will handle the conversion
2263                trace!(
2264                    "begin_inner: Creating frame for inner type {} (parent is {})",
2265                    inner_shape, parent_shape
2266                );
2267                self.frames
2268                    .push(Frame::new(inner_data, inner_shape, FrameOwnership::Owned));
2269
2270                Ok(self)
2271            } else {
2272                // For wrapper types without try_from, navigate to the first field
2273                // This is a common pattern for newtype wrappers
2274                trace!(
2275                    "begin_inner: No try_from for {}, using field navigation",
2276                    parent_shape
2277                );
2278                self.begin_nth_field(0)
2279            }
2280        } else {
2281            Err(ReflectError::OperationFailed {
2282                shape: parent_shape,
2283                operation: "type does not have an inner value",
2284            })
2285        }
2286    }
2287
2288    /// Copy a value from a Peek into the current position (safe alternative to set_shape)
2289    pub fn set_from_peek(
2290        &mut self,
2291        peek: &Peek<'_, '_, 'shape>,
2292    ) -> Result<&mut Self, ReflectError<'shape>> {
2293        self.require_active()?;
2294
2295        // Get the source value's pointer and shape
2296        let src_ptr = peek.data();
2297        let src_shape = peek.shape();
2298
2299        // Safety: This is a safe wrapper around set_shape
2300        // The peek guarantees the source data is valid for its shape
2301        unsafe { self.set_shape(src_ptr.thin().unwrap(), src_shape) }
2302    }
2303
2304    /// Copy a field from a struct's default value (safe wrapper for deserialization)
2305    /// This method creates the Peek internally to avoid exposing unsafe code to callers
2306    pub fn set_field_from_default(
2307        &mut self,
2308        field_data: PtrConst<'_>,
2309        field_shape: &'shape Shape<'shape>,
2310    ) -> Result<&mut Self, ReflectError<'shape>> {
2311        self.require_active()?;
2312
2313        // Safety: The caller guarantees that field_data points to valid data for field_shape
2314        // This is typically used when copying default values during deserialization
2315        unsafe { self.set_shape(field_data, field_shape) }
2316    }
2317
2318    /// Fill all unset fields from the struct's default value
2319    /// This is a safe API for format deserializers that forbid unsafe code
2320    pub fn fill_unset_fields_from_default(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2321        self.require_active()?;
2322
2323        let frame = self.frames.last().unwrap();
2324        let shape = frame.shape;
2325
2326        // Check if this is a struct with the default attribute
2327        if !shape.has_default_attr() {
2328            return Ok(self);
2329        }
2330
2331        // Make sure we're working with a struct
2332        let struct_def = match shape.ty {
2333            Type::User(UserType::Struct(sd)) => sd,
2334            _ => return Ok(self), // Not a struct, nothing to do
2335        };
2336
2337        // Check if any fields are unset
2338        let mut has_unset = false;
2339        for index in 0..struct_def.fields.len() {
2340            if !self.is_field_set(index)? {
2341                has_unset = true;
2342                break;
2343            }
2344        }
2345
2346        if !has_unset {
2347            return Ok(self); // All fields are set, nothing to do
2348        }
2349
2350        // Create a default instance
2351        let default_val = Partial::alloc_shape(shape)?.set_default()?.build()?;
2352        let peek = default_val.peek();
2353
2354        // Convert to struct peek
2355        let struct_peek = peek
2356            .into_struct()
2357            .map_err(|_| ReflectError::OperationFailed {
2358                shape,
2359                operation: "expected struct peek for default value",
2360            })?;
2361
2362        // Copy unset fields from the default
2363        for (index, _field) in struct_def.fields.iter().enumerate() {
2364            if !self.is_field_set(index)? {
2365                self.begin_nth_field(index)?;
2366
2367                // Get the field from the default value
2368                let def_field =
2369                    struct_peek
2370                        .field(index)
2371                        .map_err(|_| ReflectError::OperationFailed {
2372                            shape,
2373                            operation: "failed to get field from default struct",
2374                        })?;
2375
2376                self.set_from_peek(&def_field)?;
2377                self.end()?;
2378            }
2379        }
2380
2381        Ok(self)
2382    }
2383
2384    /// Convenience shortcut: sets the nth element of an array directly to value, popping after.
2385    pub fn set_nth_element<U>(
2386        &mut self,
2387        idx: usize,
2388        value: U,
2389    ) -> Result<&mut Self, ReflectError<'shape>>
2390    where
2391        U: Facet<'facet>,
2392    {
2393        self.begin_nth_element(idx)?.set(value)?.end()
2394    }
2395
2396    /// Convenience shortcut: sets the field at index `idx` directly to value, popping after.
2397    pub fn set_nth_field<U>(
2398        &mut self,
2399        idx: usize,
2400        value: U,
2401    ) -> Result<&mut Self, ReflectError<'shape>>
2402    where
2403        U: Facet<'facet>,
2404    {
2405        self.begin_nth_field(idx)?.set(value)?.end()
2406    }
2407
2408    /// Convenience shortcut: sets the named field to value, popping after.
2409    pub fn set_field<U>(
2410        &mut self,
2411        field_name: &str,
2412        value: U,
2413    ) -> Result<&mut Self, ReflectError<'shape>>
2414    where
2415        U: Facet<'facet>,
2416    {
2417        self.begin_field(field_name)?.set(value)?.end()
2418    }
2419
2420    /// Convenience shortcut: sets the nth field of an enum variant directly to value, popping after.
2421    pub fn set_nth_enum_field<U>(
2422        &mut self,
2423        idx: usize,
2424        value: U,
2425    ) -> Result<&mut Self, ReflectError<'shape>>
2426    where
2427        U: Facet<'facet>,
2428    {
2429        self.begin_nth_enum_field(idx)?.set(value)?.end()
2430    }
2431
2432    /// Convenience shortcut: sets the key for a map key-value insertion, then pops after.
2433    pub fn set_key<U>(&mut self, value: U) -> Result<&mut Self, ReflectError<'shape>>
2434    where
2435        U: Facet<'facet>,
2436    {
2437        self.begin_key()?.set(value)?.end()
2438    }
2439
2440    /// Convenience shortcut: sets the value for a map key-value insertion, then pops after.
2441    pub fn set_value<U>(&mut self, value: U) -> Result<&mut Self, ReflectError<'shape>>
2442    where
2443        U: Facet<'facet>,
2444    {
2445        self.begin_value()?.set(value)?.end()
2446    }
2447
2448    /// Shorthand for: begin_list_item(), set, end
2449    pub fn push<U>(&mut self, value: U) -> Result<&mut Self, ReflectError<'shape>>
2450    where
2451        U: Facet<'facet>,
2452    {
2453        self.begin_list_item()?.set(value)?.end()
2454    }
2455}
2456
2457/// A typed wrapper around `Partial`, for when you want to statically
2458/// ensure that `build` gives you the proper type.
2459pub struct TypedPartial<'facet, 'shape, T> {
2460    inner: Partial<'facet, 'shape>,
2461    phantom: PhantomData<T>,
2462}
2463
2464impl<'facet, 'shape, T> TypedPartial<'facet, 'shape, T> {
2465    /// Unwraps the underlying Partial, consuming self.
2466    pub fn inner_mut(&mut self) -> &mut Partial<'facet, 'shape> {
2467        &mut self.inner
2468    }
2469
2470    /// Builds the value and returns a `Box<T>`
2471    pub fn build(&mut self) -> Result<Box<T>, ReflectError<'shape>>
2472    where
2473        T: Facet<'facet>,
2474        'facet: 'shape,
2475    {
2476        trace!(
2477            "TypedPartial::build: Building value for type {}, inner shape: {}",
2478            T::SHAPE,
2479            self.inner.shape()
2480        );
2481        let heap_value = self.inner.build()?;
2482        trace!(
2483            "TypedPartial::build: Built heap value with shape: {}",
2484            heap_value.shape()
2485        );
2486        // Safety: HeapValue was constructed from T and the shape layout is correct.
2487        let result = unsafe { heap_value.into_box_unchecked::<T>() };
2488        trace!("TypedPartial::build: Successfully converted to Box<T>");
2489        Ok(result)
2490    }
2491
2492    /// Sets a value wholesale into the current frame
2493    pub fn set<U>(&mut self, value: U) -> Result<&mut Self, ReflectError<'shape>>
2494    where
2495        U: Facet<'facet>,
2496    {
2497        self.inner.set(value)?;
2498        Ok(self)
2499    }
2500
2501    /// Sets a value into the current frame by shape, for shape-based operations
2502    pub fn set_shape(
2503        &mut self,
2504        src_value: PtrConst<'_>,
2505        src_shape: &'shape Shape<'shape>,
2506    ) -> Result<&mut Self, ReflectError<'shape>> {
2507        unsafe { self.inner.set_shape(src_value, src_shape)? };
2508        Ok(self)
2509    }
2510
2511    /// Forwards begin_field to the inner wip instance.
2512    pub fn begin_field(&mut self, field_name: &str) -> Result<&mut Self, ReflectError<'shape>> {
2513        self.inner.begin_field(field_name)?;
2514        Ok(self)
2515    }
2516
2517    /// Forwards begin_nth_field to the inner wip instance.
2518    pub fn begin_nth_field(&mut self, idx: usize) -> Result<&mut Self, ReflectError<'shape>> {
2519        self.inner.begin_nth_field(idx)?;
2520        Ok(self)
2521    }
2522
2523    /// Forwards begin_nth_element to the inner wip instance.
2524    pub fn begin_nth_element(&mut self, idx: usize) -> Result<&mut Self, ReflectError<'shape>> {
2525        self.inner.begin_nth_element(idx)?;
2526        Ok(self)
2527    }
2528
2529    /// Forwards begin_smart_ptr to the inner wip instance.
2530    pub fn begin_smart_ptr(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2531        self.inner.begin_smart_ptr()?;
2532        Ok(self)
2533    }
2534
2535    /// Forwards end to the inner wip instance.
2536    pub fn end(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2537        self.inner.end()?;
2538        Ok(self)
2539    }
2540
2541    /// Forwards set_default to the inner wip instance.
2542    pub fn set_default(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2543        self.inner.set_default()?;
2544        Ok(self)
2545    }
2546
2547    /// Forwards set_from_function to the inner wip instance.
2548    pub fn set_from_function<F>(&mut self, f: F) -> Result<&mut Self, ReflectError<'shape>>
2549    where
2550        F: FnOnce(PtrUninit<'_>) -> Result<(), ReflectError<'shape>>,
2551    {
2552        self.inner.set_from_function(f)?;
2553        Ok(self)
2554    }
2555
2556    /// Forwards parse_from_str to the inner wip instance.
2557    pub fn parse_from_str(&mut self, s: &str) -> Result<&mut Self, ReflectError<'shape>> {
2558        self.inner.parse_from_str(s)?;
2559        Ok(self)
2560    }
2561
2562    /// Forwards begin_variant to the inner wip instance.
2563    pub fn select_variant(&mut self, discriminant: i64) -> Result<&mut Self, ReflectError<'shape>> {
2564        self.inner.select_variant(discriminant)?;
2565        Ok(self)
2566    }
2567
2568    /// Forwards begin_variant_named to the inner wip instance.
2569    pub fn select_variant_named(
2570        &mut self,
2571        variant_name: &str,
2572    ) -> Result<&mut Self, ReflectError<'shape>> {
2573        self.inner.select_variant_named(variant_name)?;
2574        Ok(self)
2575    }
2576
2577    /// Forwards select_nth_variant to the inner wip instance.
2578    pub fn select_nth_variant(&mut self, index: usize) -> Result<&mut Self, ReflectError<'shape>> {
2579        self.inner.select_nth_variant(index)?;
2580        Ok(self)
2581    }
2582
2583    /// Forwards begin_nth_enum_field to the inner wip instance.
2584    pub fn begin_nth_enum_field(&mut self, idx: usize) -> Result<&mut Self, ReflectError<'shape>> {
2585        self.inner.begin_nth_enum_field(idx)?;
2586        Ok(self)
2587    }
2588
2589    /// Forwards begin_pushback to the inner wip instance.
2590    pub fn begin_list(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2591        self.inner.begin_list()?;
2592        Ok(self)
2593    }
2594
2595    /// Forwards begin_list_item to the inner wip instance.
2596    pub fn begin_list_item(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2597        self.inner.begin_list_item()?;
2598        Ok(self)
2599    }
2600
2601    /// Forwards begin_map to the inner wip instance.
2602    pub fn begin_map(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2603        self.inner.begin_map()?;
2604        Ok(self)
2605    }
2606
2607    /// Forwards begin_key to the inner wip instance.
2608    pub fn begin_key(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2609        self.inner.begin_key()?;
2610        Ok(self)
2611    }
2612
2613    /// Forwards begin_value to the inner wip instance.
2614    pub fn begin_value(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2615        self.inner.begin_value()?;
2616        Ok(self)
2617    }
2618
2619    /// Returns a human-readable path representing the current traversal in the builder,
2620    /// e.g., `RootStruct.fieldName[index].subfield`.
2621    pub fn path(&self) -> String {
2622        self.inner.path()
2623    }
2624
2625    /// Returns the shape of the current frame.
2626    pub fn shape(&self) -> &'shape Shape<'shape> {
2627        self.inner.shape()
2628    }
2629
2630    /// Convenience shortcut: sets the nth element of an array directly to value, popping after.
2631    pub fn set_nth_element<U>(
2632        &mut self,
2633        idx: usize,
2634        value: U,
2635    ) -> Result<&mut Self, ReflectError<'shape>>
2636    where
2637        U: Facet<'facet>,
2638    {
2639        self.inner.set_nth_element(idx, value)?;
2640        Ok(self)
2641    }
2642
2643    /// Convenience shortcut: sets the field at index `idx` directly to value, popping after.
2644    pub fn set_nth_field<U>(
2645        &mut self,
2646        idx: usize,
2647        value: U,
2648    ) -> Result<&mut Self, ReflectError<'shape>>
2649    where
2650        U: Facet<'facet>,
2651    {
2652        self.inner.set_nth_field(idx, value)?;
2653        Ok(self)
2654    }
2655
2656    /// Convenience shortcut: sets the named field to value, popping after.
2657    pub fn set_field<U>(
2658        &mut self,
2659        field_name: &str,
2660        value: U,
2661    ) -> Result<&mut Self, ReflectError<'shape>>
2662    where
2663        U: Facet<'facet>,
2664    {
2665        self.inner.set_field(field_name, value)?;
2666        Ok(self)
2667    }
2668
2669    /// Convenience shortcut: sets the nth field of an enum variant directly to value, popping after.
2670    pub fn set_nth_enum_field<U>(
2671        &mut self,
2672        idx: usize,
2673        value: U,
2674    ) -> Result<&mut Self, ReflectError<'shape>>
2675    where
2676        U: Facet<'facet>,
2677    {
2678        self.inner.set_nth_enum_field(idx, value)?;
2679        Ok(self)
2680    }
2681
2682    /// Convenience shortcut: sets the key for a map key-value insertion, then pops after.
2683    pub fn set_key<U>(&mut self, value: U) -> Result<&mut Self, ReflectError<'shape>>
2684    where
2685        U: Facet<'facet>,
2686    {
2687        self.inner.set_key(value)?;
2688        Ok(self)
2689    }
2690
2691    /// Convenience shortcut: sets the value for a map key-value insertion, then pops after.
2692    pub fn set_value<U>(&mut self, value: U) -> Result<&mut Self, ReflectError<'shape>>
2693    where
2694        U: Facet<'facet>,
2695    {
2696        self.inner.set_value(value)?;
2697        Ok(self)
2698    }
2699
2700    /// Forwards push to the inner wip instance.
2701    pub fn push<U>(&mut self, value: U) -> Result<&mut Self, ReflectError<'shape>>
2702    where
2703        U: Facet<'facet>,
2704    {
2705        self.inner.push(value)?;
2706        Ok(self)
2707    }
2708
2709    /// Forwards begin_some to the inner wip instance.
2710    pub fn begin_some(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2711        self.inner.begin_some()?;
2712        Ok(self)
2713    }
2714
2715    /// Forwards begin_inner to the inner wip instance.
2716    pub fn begin_inner(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2717        self.inner.begin_inner()?;
2718        Ok(self)
2719    }
2720}
2721
2722impl<'facet, 'shape, T> core::fmt::Debug for TypedPartial<'facet, 'shape, T> {
2723    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2724        f.debug_struct("TypedPartial")
2725            .field("shape", &self.inner.frames.last().map(|frame| frame.shape))
2726            .finish()
2727    }
2728}
2729
2730impl<'facet, 'shape> Drop for Partial<'facet, 'shape> {
2731    fn drop(&mut self) {
2732        trace!("๐Ÿงน Partial is being dropped");
2733
2734        // We need to properly drop all initialized fields
2735        while let Some(frame) = self.frames.pop() {
2736            match &frame.tracker {
2737                Tracker::Uninit => {
2738                    // Nothing was initialized, nothing to drop
2739                }
2740                Tracker::Init => {
2741                    // Fully initialized, drop it
2742                    if let Some(drop_fn) =
2743                        frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
2744                    {
2745                        unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
2746                    }
2747                }
2748                Tracker::Array { iset, .. } => {
2749                    // Drop initialized array elements
2750                    if let Type::Sequence(facet_core::SequenceType::Array(array_def)) =
2751                        frame.shape.ty
2752                    {
2753                        let element_layout = array_def.t.layout.sized_layout().ok();
2754                        if let Some(layout) = element_layout {
2755                            for idx in 0..array_def.n {
2756                                if iset.get(idx) {
2757                                    let offset = layout.size() * idx;
2758                                    let element_ptr = unsafe { frame.data.field_init_at(offset) };
2759                                    if let Some(drop_fn) =
2760                                        array_def.t.vtable.sized().and_then(|v| (v.drop_in_place)())
2761                                    {
2762                                        unsafe { drop_fn(element_ptr) };
2763                                    }
2764                                }
2765                            }
2766                        }
2767                    }
2768                }
2769                Tracker::Struct { iset, .. } => {
2770                    // Drop initialized struct fields
2771                    if let Type::User(UserType::Struct(struct_type)) = frame.shape.ty {
2772                        for (idx, field) in struct_type.fields.iter().enumerate() {
2773                            if iset.get(idx) {
2774                                // This field was initialized, drop it
2775                                let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
2776                                if let Some(drop_fn) =
2777                                    field.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
2778                                {
2779                                    unsafe { drop_fn(field_ptr) };
2780                                }
2781                            }
2782                        }
2783                    }
2784                }
2785                Tracker::Enum { variant, data, .. } => {
2786                    // Drop initialized enum variant fields
2787                    for (idx, field) in variant.data.fields.iter().enumerate() {
2788                        if data.get(idx) {
2789                            // This field was initialized, drop it
2790                            let field_ptr =
2791                                unsafe { frame.data.as_mut_byte_ptr().add(field.offset) };
2792                            if let Some(drop_fn) =
2793                                field.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
2794                            {
2795                                unsafe { drop_fn(PtrMut::new(field_ptr)) };
2796                            }
2797                        }
2798                    }
2799                }
2800                Tracker::SmartPointer { is_initialized } => {
2801                    // Drop the initialized Box
2802                    if *is_initialized {
2803                        if let Some(drop_fn) =
2804                            frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
2805                        {
2806                            unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
2807                        }
2808                    }
2809                    // Note: we don't deallocate the inner value here because
2810                    // the Box's drop will handle that
2811                }
2812                Tracker::List { is_initialized, .. } => {
2813                    // Drop the initialized List
2814                    if *is_initialized {
2815                        if let Some(drop_fn) =
2816                            frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
2817                        {
2818                            unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
2819                        }
2820                    }
2821                }
2822                Tracker::Map {
2823                    is_initialized,
2824                    insert_state,
2825                } => {
2826                    // Drop the initialized Map
2827                    if *is_initialized {
2828                        if let Some(drop_fn) =
2829                            frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
2830                        {
2831                            unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
2832                        }
2833                    }
2834
2835                    // Clean up any in-progress insertion state
2836                    match insert_state {
2837                        MapInsertState::PushingKey { key_ptr } => {
2838                            if let Some(key_ptr) = key_ptr {
2839                                // Deallocate the key buffer
2840                                if let Def::Map(map_def) = frame.shape.def {
2841                                    if let Ok(key_shape) = map_def.k().layout.sized_layout() {
2842                                        if key_shape.size() > 0 {
2843                                            unsafe {
2844                                                alloc::alloc::dealloc(
2845                                                    key_ptr.as_mut_byte_ptr(),
2846                                                    key_shape,
2847                                                )
2848                                            };
2849                                        }
2850                                    }
2851                                }
2852                            }
2853                        }
2854                        MapInsertState::PushingValue { key_ptr, value_ptr } => {
2855                            // Drop and deallocate both key and value buffers
2856                            if let Def::Map(map_def) = frame.shape.def {
2857                                // Drop and deallocate the key
2858                                if let Some(drop_fn) =
2859                                    map_def.k().vtable.sized().and_then(|v| (v.drop_in_place)())
2860                                {
2861                                    unsafe { drop_fn(PtrMut::new(key_ptr.as_mut_byte_ptr())) };
2862                                }
2863                                if let Ok(key_shape) = map_def.k().layout.sized_layout() {
2864                                    if key_shape.size() > 0 {
2865                                        unsafe {
2866                                            alloc::alloc::dealloc(
2867                                                key_ptr.as_mut_byte_ptr(),
2868                                                key_shape,
2869                                            )
2870                                        };
2871                                    }
2872                                }
2873
2874                                // Drop and deallocate the value if it exists
2875                                if let Some(value_ptr) = value_ptr {
2876                                    if let Ok(value_shape) = map_def.v().layout.sized_layout() {
2877                                        if value_shape.size() > 0 {
2878                                            unsafe {
2879                                                alloc::alloc::dealloc(
2880                                                    value_ptr.as_mut_byte_ptr(),
2881                                                    value_shape,
2882                                                )
2883                                            };
2884                                        }
2885                                    }
2886                                }
2887                            }
2888                        }
2889                        MapInsertState::Idle => {}
2890                    }
2891                }
2892                Tracker::Option { building_inner } => {
2893                    // If we're building the inner value, it will be handled by the Option vtable
2894                    // No special cleanup needed here as the Option will either be properly
2895                    // initialized or remain uninitialized
2896                    if !building_inner {
2897                        // Option is fully initialized, drop it normally
2898                        if let Some(drop_fn) =
2899                            frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
2900                        {
2901                            unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
2902                        }
2903                    }
2904                }
2905            }
2906
2907            // Only deallocate if this frame owns the allocation
2908            if let FrameOwnership::Owned = frame.ownership {
2909                if let Ok(layout) = frame.shape.layout.sized_layout() {
2910                    if layout.size() > 0 {
2911                        unsafe { alloc::alloc::dealloc(frame.data.as_mut_byte_ptr(), layout) };
2912                    }
2913                }
2914            }
2915        }
2916    }
2917}