1use crate::{ReflectError, ValueId};
2use alloc::{format, string::ToString};
3use alloc::{vec, vec::Vec};
4use bitflags::bitflags;
5use core::{fmt, marker::PhantomData};
6use facet_core::{Def, Facet, FieldError, PtrConst, PtrMut, PtrUninit, Shape, Variant};
7use flat_map::FlatMap;
8use log::trace;
9use yansi::Paint as _;
10
11use alloc::string::String;
12
13mod iset;
14pub use iset::*;
15
16mod enum_;
17mod flat_map;
18
19mod heap_value;
20pub use heap_value::*;
21
22fn def_kind(def: &Def) -> &'static str {
23 match def {
24 Def::Scalar(_) => "scalar",
25 Def::Struct(_) => "struct",
26 Def::Map(_) => "map",
27 Def::List(_) => "list",
28 Def::Enum(_) => "enum",
29 Def::Option(_) => "option",
30 Def::SmartPointer(_) => "smart_ptr",
31 _ => "other",
32 }
33}
34
35pub struct Frame {
37 data: PtrUninit<'static>,
39
40 shape: &'static Shape,
42
43 field_index_in_parent: Option<usize>,
46
47 istate: IState,
51}
52
53impl Frame {
54 fn recompose(id: ValueId, istate: IState) -> Self {
56 Frame {
57 data: PtrUninit::new(id.ptr as *mut u8),
58 shape: id.shape,
59 field_index_in_parent: None,
60 istate,
61 }
62 }
63
64 fn dealloc_if_needed(&mut self) {
66 if self.istate.flags.contains(FrameFlags::ALLOCATED) {
67 trace!(
68 "[{}] {:p} => deallocating {}",
69 self.istate.depth,
70 self.data.as_mut_byte_ptr().magenta(),
71 self.shape.green(),
72 );
73 if self.shape.layout.size() != 0 {
74 trace!("Ok I swear we're deallocating it");
75 unsafe {
76 alloc::alloc::dealloc(self.data.as_mut_byte_ptr(), self.shape.layout);
77 }
78 }
79 self.istate.flags.remove(FrameFlags::ALLOCATED);
80 } else {
81 trace!(
82 "[{}] {:p} => NOT deallocating {} (not ALLOCATED)",
83 self.istate.depth,
84 self.data.as_mut_byte_ptr().magenta(),
85 self.shape.green(),
86 );
87 }
88 }
89}
90
91struct DebugToDisplay<T>(T);
92
93impl<T> fmt::Debug for DebugToDisplay<T>
94where
95 T: fmt::Display,
96{
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 fmt::Display::fmt(&self.0, f)
99 }
100}
101
102impl fmt::Debug for Frame {
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 f.debug_struct("Frame")
105 .field("shape", &DebugToDisplay(&self.shape))
106 .field("kind", &def_kind(&self.shape.def))
107 .field("index", &self.field_index_in_parent)
108 .field("mode", &self.istate.mode)
109 .finish()
110 }
111}
112
113impl Frame {
114 fn id(&self) -> ValueId {
116 ValueId::new(self.shape, self.data.as_byte_ptr())
117 }
118
119 fn is_fully_initialized(&self) -> bool {
121 match self.shape.def {
122 Def::Struct(sd) => self.istate.fields.are_all_set(sd.fields.len()),
123 Def::Enum(_) => match self.istate.variant.as_ref() {
124 None => false,
125 Some(v) => self.istate.fields.are_all_set(v.data.fields.len()),
126 },
127 _ => self.istate.fields.are_all_set(1),
128 }
129 }
130
131 unsafe fn drop_and_dealloc_if_needed(mut self) {
133 trace!(
134 "[Frame::drop] Dropping frame for shape {} at {:p}",
135 self.shape.blue(),
136 self.data.as_byte_ptr()
137 );
138 if let Some(drop_in_place) = self.shape.vtable.drop_in_place {
139 unsafe {
140 trace!(
141 "[Frame::drop] Invoking drop_in_place for shape {} at {:p}",
142 self.shape.green(),
143 self.data.as_byte_ptr()
144 );
145 drop_in_place(self.data.assume_init());
146 }
147 } else {
148 trace!(
149 "[Frame::drop] No drop_in_place function for shape {}",
150 self.shape.blue(),
151 );
152 }
153 self.dealloc_if_needed();
154 }
155
156 unsafe fn mark_fully_initialized(&mut self) {
158 match self.shape.def {
159 Def::Struct(sd) => {
160 self.istate.fields = ISet::all(sd.fields);
161 }
162 Def::Enum(_) => {
163 if let Some(variant) = &self.istate.variant {
164 self.istate.fields = ISet::all(variant.data.fields);
165 }
166 }
167 _ => {
168 self.istate.fields.set(0);
169 }
170 }
171 }
172
173 unsafe fn mark_uninitialized(&mut self) {
175 ISet::clear(&mut self.istate.fields);
176 self.istate.variant = None;
177 }
178
179 unsafe fn mark_moved_out_of(&mut self) {
180 self.dealloc_if_needed();
181 unsafe { self.mark_uninitialized() };
182 self.istate.flags.insert(FrameFlags::MOVED);
183 }
184}
185
186struct IState {
188 variant: Option<Variant>,
190
191 fields: ISet,
193
194 depth: usize,
196
197 mode: FrameMode,
199
200 flags: FrameFlags,
202
203 list_index: Option<usize>,
205
206 #[allow(dead_code)]
208 map_key: Option<String>,
209}
210
211bitflags! {
212 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
214 pub struct FrameFlags: u64 {
215 const EMPTY = 0;
217
218 const ALLOCATED = 1 << 0;
220
221 const MOVED = 1 << 1;
225 }
226
227 }
229
230impl IState {
231 pub fn new(depth: usize, mode: FrameMode, flags: FrameFlags) -> Self {
233 Self {
234 variant: None,
235 fields: Default::default(),
236 depth,
237 mode,
238 flags,
239 list_index: None,
240 map_key: None,
241 }
242 }
243
244 #[allow(dead_code)]
246 pub fn with_list_index(mut self, index: usize) -> Self {
247 self.list_index = Some(index);
248 self
249 }
250
251 #[allow(dead_code)]
253 pub fn with_map_key(mut self, key: String) -> Self {
254 self.map_key = Some(key);
255 self
256 }
257}
258
259#[derive(Debug, Clone, Copy, PartialEq, Eq)]
261pub enum FrameMode {
262 Root,
264 Normal,
266 ListElement,
268 MapKey,
270 MapValue {
272 index: usize,
274 },
275 OptionSome,
277 OptionNone,
280}
281
282pub struct Wip<'a> {
284 frames: alloc::vec::Vec<Frame>,
286
287 istates: FlatMap<ValueId, IState>,
289
290 phantom: PhantomData<&'a ()>,
292}
293
294impl<'a> Wip<'a> {
295 pub fn frames_count(&self) -> usize {
297 self.frames.len()
298 }
299
300 pub fn alloc_shape(shape: &'static Shape) -> Self {
302 let data = shape.allocate();
303 Self {
304 frames: alloc::vec![Frame {
305 data,
306 shape,
307 field_index_in_parent: None,
308 istate: IState::new(0, FrameMode::Root, FrameFlags::ALLOCATED),
309 }],
310 istates: Default::default(),
311 phantom: PhantomData,
312 }
313 }
314
315 pub fn alloc<S: Facet>() -> Self {
317 Self::alloc_shape(S::SHAPE)
318 }
319
320 fn track(&mut self, frame: Frame) {
321 if frame.istate.flags.contains(FrameFlags::MOVED) {
322 return;
324 }
325 self.istates.insert(frame.id(), frame.istate);
326 }
327
328 pub fn shape(&self) -> &'static Shape {
330 self.frames.last().unwrap().shape
331 }
332
333 pub fn in_option(&self) -> bool {
335 let Some(frame) = self.frames.last() else {
336 return false;
337 };
338 matches!(frame.istate.mode, FrameMode::OptionSome)
339 }
340
341 pub fn mode(&self) -> FrameMode {
343 self.frames.last().unwrap().istate.mode
344 }
345
346 pub fn build(mut self) -> Result<HeapValue<'a>, ReflectError> {
348 trace!("[{}] ⚒️ It's BUILD time", self.frames.len());
349
350 while let Some(frame) = self.pop_inner() {
352 self.track(frame);
353 }
354
355 let Some((root_id, _)) = self.istates.iter().find(|(_k, istate)| istate.depth == 0) else {
357 trace!("No root found, possibly already built or empty WIP");
358 return Err(ReflectError::OperationFailed {
359 shape: <()>::SHAPE,
360 operation: "tried to build a value but there was no root frame tracked",
361 });
362 };
363
364 let root_id = *root_id;
365 let root_istate = self
368 .istates
369 .remove(&root_id)
370 .expect("Root ID found but not present in istates, this is a bug"); let root_frame = Frame::recompose(root_id, root_istate);
373 let root_shape = root_frame.shape;
374 let root_data_ptr = root_frame.data; let guard = Guard {
381 ptr: root_data_ptr.as_mut_byte_ptr(),
382 layout: root_shape.layout,
383 };
384
385 let mut to_check = alloc::vec![root_frame];
387
388 while let Some(frame) = to_check.pop() {
390 trace!(
391 "Checking frame: shape={} at {:p}, flags={:?}, mode={:?}",
392 frame.shape.blue(),
393 frame.data.as_byte_ptr(),
394 frame.istate.flags.bright_magenta(),
395 frame.istate.mode,
396 );
397
398 if frame.istate.flags.contains(FrameFlags::MOVED) {
400 trace!(
401 "{}",
402 "Frame was moved out of, skipping initialization check".yellow()
403 );
404 continue;
405 }
406
407 match frame.shape.def {
409 Def::Struct(sd) => {
410 if !frame.is_fully_initialized() {
411 for i in 0..sd.fields.len() {
413 if !frame.istate.fields.has(i) {
414 let field = &sd.fields[i];
415 return Err(ReflectError::UninitializedField {
416 shape: frame.shape,
417 field_name: field.name,
418 });
419 }
420 }
421 unreachable!(
423 "Enum variant not fully initialized but couldn't find which field"
424 );
425 }
426
427 for (i, field) in sd.fields.iter().enumerate() {
429 let field_shape = field.shape();
430 let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
431 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
432
433 if let Some(field_istate) = self.istates.remove(&field_id) {
434 trace!(
435 "Queueing struct field check: #{} '{}' of {}: shape={}, ptr={:p}",
436 i.to_string().bright_cyan(),
437 field.name.bright_blue(),
438 frame.shape.blue(),
439 field_shape.green(),
440 field_ptr.as_byte_ptr()
441 );
442 let field_frame = Frame::recompose(field_id, field_istate);
443 to_check.push(field_frame);
444 }
445 }
446 }
447 Def::Enum(_ed) => {
448 if let Some(variant) = &frame.istate.variant {
449 if !frame.istate.fields.are_all_set(variant.data.fields.len()) {
450 for (i, field) in variant.data.fields.iter().enumerate() {
452 if !frame.istate.fields.has(i) {
453 return Err(ReflectError::UninitializedEnumField {
454 shape: frame.shape,
455 variant_name: variant.name,
456 field_name: field.name,
457 });
458 }
459 }
460 unreachable!(
462 "Enum variant not fully initialized but couldn't find which field"
463 );
464 }
465
466 for (i, field) in variant.data.fields.iter().enumerate() {
468 let field_shape = field.shape();
469 let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
473 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
474
475 if let Some(field_istate) = self.istates.remove(&field_id) {
476 trace!(
477 "Queueing enum field check: #{} '{}' of variant '{}' of {}: shape={}, ptr={:p}",
478 i.to_string().bright_cyan(),
479 field.name.bright_blue(),
480 variant.name.yellow(),
481 frame.shape.blue(),
482 field_shape.green(),
483 field_ptr.as_byte_ptr()
484 );
485 let field_frame = Frame::recompose(field_id, field_istate);
486 to_check.push(field_frame);
487 }
488 }
489 } else {
490 return Err(ReflectError::NoVariantSelected { shape: frame.shape });
492 }
493 }
494 Def::List(_)
498 | Def::Map(_)
499 | Def::Option(_)
500 | Def::Scalar(_)
501 | Def::SmartPointer(_)
502 | Def::Array(_)
503 | Def::Slice(_) => {
504 if !frame.istate.fields.are_all_set(1) {
505 match frame.istate.mode {
507 FrameMode::OptionNone => {
508 return Err(ReflectError::UninitializedValue {
510 shape: frame.shape,
511 });
512 }
513 _ => {
515 return Err(ReflectError::UninitializedValue {
516 shape: frame.shape,
517 });
518 }
519 }
520 }
521 }
529 _ => {
531 if !frame.istate.fields.are_all_set(1) {
533 return Err(ReflectError::UninitializedValue { shape: frame.shape });
534 }
535 }
536 }
537 }
538
539 trace!("All reachable frames checked and initialized.");
541
542 let data = unsafe { root_data_ptr.assume_init() };
544 if let Some(invariant_fn) = root_shape.vtable.invariants {
545 trace!(
546 "Checking invariants for root shape {} at {:p}",
547 root_shape.green(),
548 data.as_byte_ptr()
549 );
550 if !unsafe { invariant_fn(PtrConst::new(data.as_byte_ptr())) } {
551 return Err(ReflectError::InvariantViolation {
552 invariant: "Custom validation function returned false",
553 });
554 }
555 } else {
556 trace!(
557 "No invariants to check for root shape {}",
558 root_shape.blue()
559 );
560 }
561
562 FlatMap::clear(&mut self.istates); Ok(HeapValue {
565 guard: Some(guard),
566 shape: root_shape,
567 phantom: PhantomData,
568 })
569 }
570
571 pub fn field(mut self, index: usize) -> Result<Self, ReflectError> {
583 let frame = self.frames.last_mut().unwrap();
584 let shape = frame.shape;
585
586 let (field, field_offset) = match shape.def {
587 Def::Struct(def) => {
588 if index >= def.fields.len() {
589 return Err(ReflectError::FieldError {
590 shape,
591 field_error: FieldError::NoSuchField,
592 });
593 }
594 let field = &def.fields[index];
595 (field, field.offset)
596 }
597 Def::Enum(_) => {
598 let Some(variant) = frame.istate.variant.as_ref() else {
599 return Err(ReflectError::OperationFailed {
600 shape,
601 operation: "tried to access a field but no variant was selected",
602 });
603 };
604
605 if index >= variant.data.fields.len() {
606 return Err(ReflectError::FieldError {
607 shape,
608 field_error: FieldError::NoSuchField,
609 });
610 }
611
612 let field = &variant.data.fields[index];
613 (field, field.offset)
614 }
615 _ => {
616 return Err(ReflectError::WasNotA {
617 expected: "struct or enum",
618 actual: shape,
619 });
620 }
621 };
622
623 let field_data = unsafe { frame.data.field_uninit_at(field_offset) };
624
625 let mut frame = Frame {
626 data: field_data,
627 shape: field.shape(),
628 field_index_in_parent: Some(index),
629 istate: IState::new(self.frames.len(), FrameMode::Normal, FrameFlags::EMPTY),
631 };
632 trace!(
633 "[{}] Selecting field {} ({}#{}) of {}",
634 self.frames.len(),
635 field.name.blue(),
636 field.shape().green(),
637 index.yellow(),
638 shape.blue(),
639 );
640 if let Some(iset) = self.istates.remove(&frame.id()) {
641 trace!(
642 "[{}] Restoring saved state for {}",
643 self.frames.len(),
644 frame.id().shape.blue()
645 );
646 frame.istate = iset;
647 }
648 self.frames.push(frame);
649 Ok(self)
650 }
651
652 pub fn field_index(&self, name: &str) -> Option<usize> {
664 let frame = self.frames.last()?;
665 match frame.shape.def {
666 Def::Struct(def) => def.fields.iter().position(|f| f.name == name),
667 Def::Enum(_) => {
668 let variant = frame.istate.variant.as_ref()?;
670 variant.data.fields.iter().position(|f| f.name == name)
671 }
672 _ => None,
673 }
674 }
675
676 pub fn field_named(self, name: &str) -> Result<Self, ReflectError> {
688 let frame = self.frames.last().unwrap();
689 let shape = frame.shape;
690
691 if let Def::Enum(_) = shape.def {
693 if frame.istate.variant.is_none() {
694 return Err(ReflectError::OperationFailed {
695 shape,
696 operation: "tried to access a field by name but no variant was selected",
697 });
698 }
699 }
700
701 let index = self.field_index(name).ok_or(ReflectError::FieldError {
702 shape,
703 field_error: FieldError::NoSuchField,
704 })?;
705
706 self.field(index)
707 }
708
709 pub fn put<'val, T: Facet + 'val>(mut self, t: T) -> Result<Wip<'val>, ReflectError>
720 where
721 'a: 'val,
722 {
723 let Some(frame) = self.frames.last_mut() else {
724 return Err(ReflectError::OperationFailed {
725 shape: T::SHAPE,
726 operation: "tried to put a T but there was no frame to put T into",
727 });
728 };
729
730 if !frame.shape.is_type::<T>() {
732 if frame.shape.is_type::<Option<T>>() {
734 trace!("Putting into an option!");
735 let Def::Option(od) = frame.shape.def else {
736 unreachable!()
737 };
738
739 let src = PtrConst::new(&raw const t);
741 if frame.istate.fields.is_any_set() {
742 let data = unsafe { frame.data.assume_init() };
743 unsafe { (od.vtable.replace_with_fn)(data, Some(src)) };
744 } else {
745 let data = frame.data;
746 unsafe { (od.vtable.init_some_fn)(data, src) };
747 }
748 unsafe {
749 frame.mark_fully_initialized();
750 }
751 let shape = frame.shape;
754 let index = frame.field_index_in_parent;
755
756 self.mark_field_as_initialized(shape, index)?;
758
759 trace!("[{}] Just put a {} value", self.frames.len(), shape.green());
760
761 return Ok(self);
762 }
763
764 return Err(ReflectError::WrongShape {
765 expected: frame.shape,
766 actual: T::SHAPE,
767 });
768 }
769
770 if frame.istate.variant.is_some() || frame.istate.fields.is_any_set() {
772 trace!(
773 "De-initializing partially initialized fields for {}",
774 frame.shape
775 );
776
777 match frame.shape.def {
778 Def::Struct(sd) => {
779 for (i, field) in sd.fields.iter().enumerate() {
780 if frame.istate.fields.has(i) {
781 if let Some(drop_fn) = field.shape().vtable.drop_in_place {
782 unsafe {
783 let field_ptr = frame.data.as_mut_byte_ptr().add(field.offset);
784 drop_fn(PtrMut::new(field_ptr));
785 }
786 }
787 }
788 }
789 }
790 Def::Enum(_) => {
791 if let Some(variant) = &frame.istate.variant {
792 for (i, field) in variant.data.fields.iter().enumerate() {
793 if frame.istate.fields.has(i) {
794 if let Some(drop_fn) = field.shape().vtable.drop_in_place {
795 unsafe {
796 let field_ptr =
797 frame.data.as_mut_byte_ptr().add(field.offset);
798 drop_fn(PtrMut::new(field_ptr));
799 }
800 }
801 }
802 }
803 }
804 }
805 _ => {
806 }
808 }
809
810 frame.istate.variant = None;
812 ISet::clear(&mut frame.istate.fields);
813 }
814
815 unsafe {
816 frame.data.put(t);
817 frame.mark_fully_initialized();
818 }
819
820 let shape = frame.shape;
821 let index = frame.field_index_in_parent;
822
823 self.mark_field_as_initialized(shape, index)?;
825
826 trace!("[{}] Just put a {} value", self.frames.len(), shape.green());
827
828 Ok(self)
829 }
830
831 pub fn parse(mut self, s: &str) -> Result<Self, ReflectError> {
833 let Some(frame) = self.frames.last_mut() else {
834 return Err(ReflectError::OperationFailed {
835 shape: <()>::SHAPE,
836 operation: "tried to parse value but there was no frame",
837 });
838 };
839
840 let shape = frame.shape;
841 let index = frame.field_index_in_parent;
842
843 let Some(parse_fn) = frame.shape.vtable.parse else {
844 return Err(ReflectError::OperationFailed {
845 shape: frame.shape,
846 operation: "type does not implement Parse",
847 });
848 };
849 match unsafe { (parse_fn)(s, frame.data) } {
850 Ok(_res) => {
851 unsafe {
852 frame.mark_fully_initialized();
853 }
854
855 self.mark_field_as_initialized(shape, index)?;
857
858 Ok(self)
859 }
860 Err(_) => Err(ReflectError::OperationFailed {
861 shape,
862 operation: "parsing",
863 }),
864 }
865 }
866
867 pub fn put_default(mut self) -> Result<Self, ReflectError> {
869 let Some(frame) = self.frames.last_mut() else {
870 return Err(ReflectError::OperationFailed {
871 shape: <()>::SHAPE,
872 operation: "tried to put default value but there was no frame",
873 });
874 };
875
876 let vtable = frame.shape.vtable;
877
878 let Some(default_in_place) = vtable.default_in_place else {
879 return Err(ReflectError::OperationFailed {
880 shape: frame.shape,
881 operation: "type does not implement Default",
882 });
883 };
884 unsafe {
885 default_in_place(frame.data);
886 frame.mark_fully_initialized();
887 }
888
889 let shape = frame.shape;
890 let index = frame.field_index_in_parent;
891
892 self.mark_field_as_initialized(shape, index)?;
894
895 Ok(self)
896 }
897
898 fn mark_field_as_initialized(
900 &mut self,
901 shape: &'static Shape,
902 index: Option<usize>,
903 ) -> Result<(), ReflectError> {
904 if let Some(index) = index {
905 let parent_index = self.frames.len().saturating_sub(2);
906 let num_frames = self.frames.len();
907 let Some(parent) = self.frames.get_mut(parent_index) else {
908 return Err(ReflectError::OperationFailed {
909 shape,
910 operation: "was supposed to mark a field as initialized, but there was no parent frame",
911 });
912 };
913 let parent_shape = parent.shape;
914 trace!(
915 "[{}] {}.{} initialized with {}",
916 num_frames,
917 parent_shape.blue(),
918 index.yellow(),
919 shape.green()
920 );
921
922 if matches!(parent.shape.def, Def::Enum(_)) && parent.istate.variant.is_none() {
923 return Err(ReflectError::OperationFailed {
924 shape,
925 operation: "was supposed to mark a field as initialized, but the parent frame was an enum and didn't have a variant chosen",
926 });
927 }
928
929 if parent.istate.fields.has(index) {
930 return Err(ReflectError::OperationFailed {
931 shape,
932 operation: "was supposed to mark a field as initialized, but the parent frame already had it marked as initialized",
933 });
934 }
935
936 parent.istate.fields.set(index);
937 }
938 Ok(())
939 }
940
941 pub fn element_shape(&self) -> Result<&'static Shape, ReflectError> {
943 let frame = self.frames.last().unwrap();
944 let shape = frame.shape;
945
946 match shape.def {
947 Def::List(list_def) => Ok(list_def.t()),
948 _ => Err(ReflectError::WasNotA {
949 expected: "list or array",
950 actual: shape,
951 }),
952 }
953 }
954
955 pub fn key_shape(&self) -> Result<&'static Shape, ReflectError> {
957 let frame = self.frames.last().unwrap();
958 let shape = frame.shape;
959
960 match shape.def {
961 Def::Map(map_def) => Ok(map_def.k),
962 _ => Err(ReflectError::WasNotA {
963 expected: "map",
964 actual: shape,
965 }),
966 }
967 }
968
969 pub fn put_empty_list(mut self) -> Result<Self, ReflectError> {
971 let Some(frame) = self.frames.last_mut() else {
972 return Err(ReflectError::OperationFailed {
973 shape: <()>::SHAPE,
974 operation: "tried to create empty list but there was no frame",
975 });
976 };
977
978 if !matches!(frame.shape.def, Def::List(_)) {
979 return Err(ReflectError::WasNotA {
980 expected: "list or array",
981 actual: frame.shape,
982 });
983 }
984
985 let vtable = frame.shape.vtable;
986
987 let Some(default_in_place) = vtable.default_in_place else {
989 return Err(ReflectError::OperationFailed {
990 shape: frame.shape,
991 operation: "list type does not implement Default",
992 });
993 };
994
995 unsafe {
996 default_in_place(frame.data);
997 frame.mark_fully_initialized();
998 }
999
1000 let shape = frame.shape;
1001 let index = frame.field_index_in_parent;
1002
1003 self.mark_field_as_initialized(shape, index)?;
1005
1006 Ok(self)
1007 }
1008
1009 pub fn put_empty_map(mut self) -> Result<Self, ReflectError> {
1011 let Some(frame) = self.frames.last_mut() else {
1012 return Err(ReflectError::OperationFailed {
1013 shape: <()>::SHAPE,
1014 operation: "tried to create empty map but there was no frame",
1015 });
1016 };
1017
1018 if !matches!(frame.shape.def, Def::Map(_)) {
1019 return Err(ReflectError::WasNotA {
1020 expected: "map or hash map",
1021 actual: frame.shape,
1022 });
1023 }
1024
1025 let vtable = frame.shape.vtable;
1026
1027 let Some(default_in_place) = vtable.default_in_place else {
1029 return Err(ReflectError::OperationFailed {
1030 shape: frame.shape,
1031 operation: "map type does not implement Default",
1032 });
1033 };
1034
1035 unsafe {
1036 default_in_place(frame.data);
1037 frame.mark_fully_initialized();
1038 }
1039
1040 let shape = frame.shape;
1041 let index = frame.field_index_in_parent;
1042
1043 self.mark_field_as_initialized(shape, index)?;
1045
1046 Ok(self)
1047 }
1048
1049 pub fn begin_pushback(mut self) -> Result<Self, ReflectError> {
1051 let Some(frame) = self.frames.last_mut() else {
1052 return Err(ReflectError::OperationFailed {
1053 shape: <()>::SHAPE,
1054 operation: "tried to begin pushback but there was no frame",
1055 });
1056 };
1057
1058 if !matches!(frame.shape.def, Def::List(_)) {
1059 return Err(ReflectError::WasNotA {
1060 expected: "list or array",
1061 actual: frame.shape,
1062 });
1063 }
1064
1065 let vtable = frame.shape.vtable;
1066
1067 if !frame.istate.fields.has(0) {
1069 let Some(default_in_place) = vtable.default_in_place else {
1070 return Err(ReflectError::OperationFailed {
1071 shape: frame.shape,
1072 operation: "list type does not implement Default",
1073 });
1074 };
1075
1076 unsafe {
1077 default_in_place(frame.data);
1078 frame.istate.fields.set(0);
1079 }
1080 }
1081
1082 Ok(self)
1083 }
1084
1085 pub fn begin_map_insert(mut self) -> Result<Self, ReflectError> {
1087 let Some(frame) = self.frames.last_mut() else {
1088 return Err(ReflectError::OperationFailed {
1089 shape: <()>::SHAPE,
1090 operation: "tried to begin map insertion but there was no frame",
1091 });
1092 };
1093
1094 if !matches!(frame.shape.def, Def::Map(_)) {
1095 return Err(ReflectError::WasNotA {
1096 expected: "map or hash map",
1097 actual: frame.shape,
1098 });
1099 }
1100
1101 let vtable = frame.shape.vtable;
1102
1103 if !frame.istate.fields.has(0) {
1105 let Some(default_in_place) = vtable.default_in_place else {
1106 return Err(ReflectError::OperationFailed {
1107 shape: frame.shape,
1108 operation: "map type does not implement Default",
1109 });
1110 };
1111
1112 unsafe {
1113 default_in_place(frame.data);
1114 frame.istate.fields.set(0);
1115 }
1116 }
1117
1118 Ok(self)
1119 }
1120
1121 pub fn push(mut self) -> Result<Self, ReflectError> {
1126 let frame = self.frames.last().unwrap();
1128 let list_shape = frame.shape;
1129
1130 if !matches!(list_shape.def, Def::List(_)) {
1131 return Err(ReflectError::WasNotA {
1132 expected: "list or array",
1133 actual: list_shape,
1134 });
1135 }
1136
1137 if !frame.istate.fields.has(0) {
1139 self = self.begin_pushback()?;
1140 }
1141
1142 let element_shape = self.element_shape()?;
1144
1145 let element_data = element_shape.allocate();
1147
1148 let mut element_frame = Frame {
1150 data: element_data,
1151 shape: element_shape,
1152 field_index_in_parent: None, istate: IState::new(
1154 self.frames.len(),
1155 FrameMode::ListElement,
1156 FrameFlags::ALLOCATED,
1157 ),
1158 };
1159
1160 trace!(
1161 "[{}] Pushing element of type {} to list {}",
1162 self.frames.len(),
1163 element_shape.green(),
1164 list_shape.blue(),
1165 );
1166
1167 if let Some(iset) = self.istates.remove(&element_frame.id()) {
1168 trace!(
1169 "[{}] Restoring saved state for {}",
1170 self.frames.len(),
1171 element_frame.id().shape.blue()
1172 );
1173 element_frame.istate = iset;
1174 }
1175
1176 self.frames.push(element_frame);
1177 Ok(self)
1178 }
1179
1180 pub fn push_some(mut self) -> Result<Self, ReflectError> {
1182 let frame = self.frames.last().unwrap();
1184 let option_shape = frame.shape;
1185
1186 if !matches!(option_shape.def, Def::Option(_)) {
1187 return Err(ReflectError::WasNotA {
1188 expected: "option",
1189 actual: option_shape,
1190 });
1191 }
1192
1193 let Def::Option(option_def) = option_shape.def else {
1195 unreachable!()
1196 };
1197
1198 let inner_shape = option_def.t();
1200
1201 let inner_data = inner_shape.allocate();
1203
1204 let mut inner_frame = Frame {
1206 data: inner_data,
1207 shape: inner_shape,
1208 field_index_in_parent: None,
1210 istate: IState::new(
1211 self.frames.len(),
1212 FrameMode::OptionSome,
1213 FrameFlags::ALLOCATED,
1215 ),
1216 };
1217
1218 trace!(
1219 "[{}] Pushing option frame for {}",
1220 self.frames.len(),
1221 option_shape.blue(),
1222 );
1223
1224 if let Some(iset) = self.istates.remove(&inner_frame.id()) {
1225 trace!(
1226 "[{}] Restoring saved state for {}",
1227 self.frames.len(),
1228 inner_frame.id().shape.blue()
1229 );
1230 inner_frame.istate = iset;
1231 }
1232
1233 self.frames.push(inner_frame);
1234 Ok(self)
1235 }
1236
1237 pub fn pop_some_push_none(mut self) -> Result<Self, ReflectError> {
1247 let Some(frame) = self.frames.last_mut() else {
1249 return Err(ReflectError::OperationFailed {
1250 shape: <()>::SHAPE,
1251 operation: "tried to pop_some_push_none but there was no frame",
1252 });
1253 };
1254
1255 if frame.istate.mode != FrameMode::OptionSome {
1257 return Err(ReflectError::OperationFailed {
1258 shape: frame.shape,
1259 operation: "pop_some_push_none called, but frame was not in Option mode",
1260 });
1261 }
1262
1263 if frame.is_fully_initialized() {
1265 return Err(ReflectError::OperationFailed {
1266 shape: frame.shape,
1267 operation: "option frame already initialized, cannot pop_some_push_none",
1268 });
1269 }
1270
1271 frame.dealloc_if_needed();
1272
1273 let _frame = self.frames.pop().expect("frame already checked");
1275
1276 let parent_frame = self
1278 .frames
1279 .last_mut()
1280 .ok_or(ReflectError::OperationFailed {
1281 shape: <()>::SHAPE,
1282 operation: "tried to pop_some_push_none but there was no parent frame",
1283 })?;
1284
1285 unsafe {
1287 if let Some(default_fn) = parent_frame.shape.vtable.default_in_place {
1288 default_fn(parent_frame.data);
1289 } else {
1290 return Err(ReflectError::OperationFailed {
1291 shape: parent_frame.shape,
1292 operation: "option type does not implement Default",
1293 });
1294 }
1295 parent_frame.mark_fully_initialized();
1296 }
1297
1298 let Def::Option(od) = parent_frame.shape.def else {
1299 return Err(ReflectError::OperationFailed {
1300 shape: parent_frame.shape,
1301 operation: "pop_some_push_none and the parent isn't of type Option???",
1302 });
1303 };
1304
1305 let data = parent_frame.data;
1307
1308 let mut frame = Frame {
1309 data,
1310 shape: od.t(),
1311 field_index_in_parent: Some(0),
1312 istate: IState::new(self.frames.len(), FrameMode::OptionNone, FrameFlags::EMPTY),
1313 };
1314 unsafe {
1315 frame.mark_fully_initialized();
1316 }
1317
1318 self.frames.push(frame);
1319
1320 Ok(self)
1321 }
1322
1323 pub fn push_map_key(mut self) -> Result<Self, ReflectError> {
1328 let frame = self.frames.last().unwrap();
1330 let map_shape = frame.shape;
1331
1332 if !matches!(map_shape.def, Def::Map(_)) {
1333 return Err(ReflectError::WasNotA {
1334 expected: "map or hash map",
1335 actual: map_shape,
1336 });
1337 }
1338
1339 if !frame.istate.fields.has(0) {
1341 self = self.begin_map_insert()?;
1342 }
1343
1344 let key_shape = self.key_shape()?;
1346
1347 let key_data = key_shape.allocate();
1349
1350 let mut key_frame = Frame {
1352 data: key_data,
1353 shape: key_shape,
1354 field_index_in_parent: None,
1355 istate: IState::new(self.frames.len(), FrameMode::MapKey, FrameFlags::ALLOCATED),
1356 };
1357
1358 trace!(
1359 "[{}] Pushing key of type {} for map {}",
1360 self.frames.len(),
1361 key_shape.green(),
1362 map_shape.blue(),
1363 );
1364
1365 if let Some(iset) = self.istates.remove(&key_frame.id()) {
1366 trace!(
1367 "[{}] Restoring saved state for {}",
1368 self.frames.len(),
1369 key_frame.id().shape.blue()
1370 );
1371 key_frame.istate = iset;
1372 }
1373
1374 self.frames.push(key_frame);
1375 Ok(self)
1376 }
1377
1378 pub fn push_map_value(mut self) -> Result<Self, ReflectError> {
1383 trace!("Wants to push map value. Frames = ");
1384 for (i, f) in self.frames.iter().enumerate() {
1385 trace!("Frame {}: {:?}", i, f);
1386 }
1387
1388 if self.frames.len() < 2 {
1390 return Err(ReflectError::OperationFailed {
1391 shape: <()>::SHAPE,
1392 operation: "tried to push map value but there was no key frame",
1393 });
1394 }
1395
1396 let key_frame_index = self.frames.len() - 1;
1398 let key_frame = &self.frames[key_frame_index];
1399
1400 match key_frame.istate.mode {
1402 FrameMode::MapKey => {} _ => {
1404 return Err(ReflectError::OperationFailed {
1405 shape: key_frame.shape,
1406 operation: "current frame is not a map key",
1407 });
1408 }
1409 }
1410
1411 if !key_frame.is_fully_initialized() {
1413 return Err(ReflectError::OperationFailed {
1414 shape: key_frame.shape,
1415 operation: "map key is not fully initialized",
1416 });
1417 }
1418
1419 let map_frame_index = self.frames.len() - 2;
1421 let map_frame = &self.frames[map_frame_index];
1422 let map_shape = map_frame.shape;
1423
1424 let Def::Map(map_def) = map_shape.def else {
1425 return Err(ReflectError::WasNotA {
1426 expected: "map",
1427 actual: map_frame.shape,
1428 });
1429 };
1430
1431 let value_shape = map_def.v;
1432
1433 let value_data = value_shape.allocate();
1435
1436 let mut value_frame = Frame {
1438 data: value_data,
1439 shape: value_shape,
1440 field_index_in_parent: None,
1441 istate: IState::new(
1442 self.frames.len(),
1443 FrameMode::MapValue {
1444 index: key_frame_index,
1445 },
1446 FrameFlags::ALLOCATED,
1447 ),
1448 };
1449
1450 trace!(
1451 "[{}] Pushing value of type {} for map {} with key type {}",
1452 self.frames.len(),
1453 value_shape.green(),
1454 map_shape.blue(),
1455 key_frame.shape.yellow(),
1456 );
1457
1458 if let Some(iset) = self.istates.remove(&value_frame.id()) {
1459 trace!(
1460 "[{}] Restoring saved state for {}",
1461 self.frames.len(),
1462 value_frame.id().shape.blue()
1463 );
1464 value_frame.istate = iset;
1465 }
1466
1467 self.frames.push(value_frame);
1468 Ok(self)
1469 }
1470
1471 pub fn pop(mut self) -> Result<Self, ReflectError> {
1473 let Some(frame) = self.pop_inner() else {
1474 return Err(ReflectError::InvariantViolation {
1475 invariant: "No frame to pop",
1476 });
1477 };
1478 self.track(frame);
1479 Ok(self)
1480 }
1481
1482 fn pop_inner(&mut self) -> Option<Frame> {
1483 let mut frame = self.frames.pop()?;
1484 let frame_shape = frame.shape;
1485
1486 let init = frame.is_fully_initialized();
1487 trace!(
1488 "[{}] {} popped, {} initialized",
1489 self.frames.len(),
1490 frame_shape.blue(),
1491 if init {
1492 "✅ fully".green()
1493 } else {
1494 "🚧 partially".red()
1495 }
1496 );
1497 if init {
1498 if let Some(parent) = self.frames.last_mut() {
1499 if let Some(index) = frame.field_index_in_parent {
1500 parent.istate.fields.set(index);
1501 }
1502 }
1503 }
1504
1505 match frame.istate.mode {
1507 FrameMode::ListElement => {
1509 if frame.is_fully_initialized() {
1510 let frame_len = self.frames.len();
1513
1514 let parent_frame = self.frames.last_mut().unwrap();
1516 let parent_shape = parent_frame.shape;
1517
1518 match parent_shape.def {
1520 Def::List(_) => {
1521 if let Def::List(list_def) = parent_shape.def {
1523 let list_vtable = list_def.vtable;
1524 trace!(
1525 "[{}] Pushing element to list {}",
1526 frame_len,
1527 parent_shape.blue()
1528 );
1529 unsafe {
1530 (list_vtable.push)(
1532 PtrMut::new(parent_frame.data.as_mut_byte_ptr()),
1533 PtrMut::new(frame.data.as_mut_byte_ptr()),
1534 );
1535 frame.mark_moved_out_of();
1536 }
1537 } else {
1538 panic!("parent frame is not a list type");
1539 }
1540 }
1541 _ => {
1542 panic!("Expected list or array, got {}", frame.shape);
1543 }
1544 }
1545 }
1546 }
1547
1548 FrameMode::MapValue {
1550 index: key_frame_index,
1551 } if frame.is_fully_initialized() => {
1552 let mut key_frame = self.frames.remove(key_frame_index);
1556
1557 if !key_frame.istate.fields.is_any_set() {
1559 panic!("key is not initialized when popping value frame");
1560 }
1561
1562 let frame_len = self.frames.len();
1564 let parent_frame = self.frames.last_mut().unwrap();
1565 let parent_shape = parent_frame.shape;
1566
1567 match parent_shape.def {
1569 Def::Map(_) => {
1570 if let Def::Map(map_def) = parent_shape.def {
1572 trace!(
1573 "[{}] Inserting key-value pair into map {}",
1574 frame_len,
1575 parent_shape.blue()
1576 );
1577 unsafe {
1578 (map_def.vtable.insert_fn)(
1580 parent_frame.data.assume_init(),
1581 key_frame.data.assume_init(),
1582 PtrMut::new(frame.data.as_mut_byte_ptr()),
1583 );
1584 key_frame.mark_moved_out_of();
1585 frame.mark_moved_out_of();
1586 }
1587 } else {
1588 panic!("parent frame is not a map type");
1589 }
1590 }
1591 _ => {
1592 panic!("Expected map or hash map, got {}", frame.shape);
1593 }
1594 }
1595 }
1596
1597 FrameMode::OptionSome => {
1599 if frame.is_fully_initialized() {
1600 trace!("Popping OptionSome (fully init'd)");
1601
1602 let frame_len = self.frames.len();
1604
1605 let parent_frame = self.frames.last_mut().unwrap();
1607 let parent_shape = parent_frame.shape;
1608
1609 match parent_shape.def {
1611 Def::Option(option_def) => {
1612 trace!(
1613 "[{}] Setting Some value in option {}",
1614 frame_len,
1615 parent_shape.blue()
1616 );
1617 unsafe {
1618 (option_def.vtable.init_some_fn)(
1620 parent_frame.data,
1621 PtrConst::new(frame.data.as_byte_ptr()),
1622 );
1623 trace!("Marking parent frame as fully initialized");
1624 parent_frame.mark_fully_initialized();
1625
1626 frame.mark_moved_out_of();
1627 }
1628 }
1629 _ => {
1630 panic!(
1631 "Expected parent frame to be an option type, got {}",
1632 frame.shape
1633 );
1634 }
1635 }
1636 } else {
1637 trace!("Popping OptionSome (not fully init'd)");
1638 }
1639 }
1640
1641 FrameMode::MapKey => {}
1644
1645 FrameMode::Normal => {}
1647
1648 _ => {}
1650 }
1651
1652 Some(frame)
1653 }
1654
1655 pub fn evict_tree(&mut self, frame: Frame) -> Frame {
1659 match frame.shape.def {
1660 Def::Struct(sd) => {
1661 for f in sd.fields {
1662 let id = ValueId {
1663 shape: f.shape(),
1664 ptr: unsafe { frame.data.field_uninit_at(f.offset) }.as_byte_ptr(),
1665 };
1666 if let Some(istate) = self.istates.remove(&id) {
1667 let frame = Frame::recompose(id, istate);
1668 self.evict_tree(frame);
1669 } else {
1670 trace!("No istate found for field {}", f.name);
1671 }
1672 }
1673 }
1674 Def::Enum(_ed) => {
1675 if let Some(variant) = &frame.istate.variant {
1677 trace!(
1678 "Evicting enum {} variant '{}' fields",
1679 frame.shape.blue(),
1680 variant.name.yellow()
1681 );
1682 for field in variant.data.fields {
1684 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
1686 let field_shape = field.shape();
1687 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
1688
1689 if let Some(field_istate) = self.istates.remove(&field_id) {
1691 trace!(
1692 "Evicting field '{}' (shape {}) of enum variant '{}'",
1693 field.name.bright_blue(),
1694 field_shape.green(),
1695 variant.name.yellow()
1696 );
1697 let field_frame = Frame::recompose(field_id, field_istate);
1699 self.evict_tree(field_frame);
1701 } else {
1702 trace!(
1703 "Field '{}' (shape {}) of enum variant '{}' not found in istates, skipping eviction",
1704 field.name.red(),
1705 field_shape.red(),
1706 variant.name.yellow()
1707 );
1708 }
1709 }
1710 } else {
1711 trace!(
1713 "Enum {} has no variant selected, no fields to evict.",
1714 frame.shape.blue()
1715 );
1716 }
1717 }
1718 _ => {}
1719 }
1720 frame
1721 }
1722
1723 #[allow(rustdoc::broken_intra_doc_links)]
1724 pub fn path(&self) -> String {
1727 let mut path = String::from("$");
1728
1729 for (i, frame) in self.frames.iter().enumerate() {
1730 if i == 0 {
1732 continue;
1733 }
1734
1735 match frame.istate.mode {
1736 FrameMode::ListElement => {
1737 if let Some(index) = frame.istate.list_index {
1739 path.push_str(&format!("[{}]", index));
1740 } else {
1741 path.push_str("[?]");
1742 }
1743 }
1744 FrameMode::MapKey => {
1745 path.push_str(".key");
1746 }
1747 FrameMode::MapValue { index: _ } => {
1748 path.push_str(".value");
1749 }
1750 FrameMode::OptionSome => {
1751 path.push_str(".some");
1752 }
1753 FrameMode::OptionNone => {
1754 path.push_str(".none");
1755 }
1756 FrameMode::Root => {
1757 }
1759 FrameMode::Normal => {
1760 if let Some(index) = frame.field_index_in_parent {
1762 if let Some(parent) = self.frames.get(i - 1) {
1764 if let Def::Struct(sd) = parent.shape.def {
1765 if index < sd.fields.len() {
1766 let field_name = sd.fields[index].name;
1767 path.push('.');
1768 path.push_str(field_name);
1769 }
1770 } else if let Def::Enum(_) = parent.shape.def {
1771 if let Some(variant) = &parent.istate.variant {
1772 if index < variant.data.fields.len() {
1773 let field_name = variant.data.fields[index].name;
1774 path.push('.');
1775 path.push_str(field_name);
1776 }
1777 }
1778 }
1779 }
1780 }
1781 }
1782 }
1783 }
1784
1785 path
1786 }
1787}
1788
1789impl Drop for Wip<'_> {
1790 fn drop(&mut self) {
1791 while let Some(frame) = self.frames.pop() {
1792 self.track(frame);
1793 }
1794 trace!("🧹 Whole WIP is dropping",);
1795
1796 let Some((root_id, _)) = self.istates.iter().find(|(_k, istate)| istate.depth == 0) else {
1797 trace!("No root found, we probably built already");
1798 return;
1799 };
1800
1801 let root_id = *root_id;
1802 let root_istate = self.istates.remove(&root_id).unwrap();
1803 let root = Frame::recompose(root_id, root_istate);
1804 let mut to_clean = vec![root];
1805
1806 let mut _root_guard: Option<Guard> = None;
1807
1808 while let Some(mut frame) = to_clean.pop() {
1809 trace!(
1810 "Cleaning frame: shape={} at {:p}, flags={:?}, mode={:?}, fully_initialized={}",
1811 frame.shape.blue(),
1812 frame.data.as_byte_ptr(),
1813 frame.istate.flags.bright_magenta(),
1814 frame.istate.mode.yellow(),
1815 if frame.is_fully_initialized() {
1816 "✅".green()
1817 } else {
1818 "❌".red()
1819 }
1820 );
1821
1822 if frame.istate.flags.contains(FrameFlags::MOVED) {
1823 trace!(
1824 "{}",
1825 "Frame was moved out of, nothing to dealloc/drop_in_place".yellow()
1826 );
1827 continue;
1828 }
1829
1830 match frame.shape.def {
1831 Def::Struct(sd) => {
1832 if frame.is_fully_initialized() {
1833 trace!(
1834 "Dropping fully initialized struct: {} at {:p}",
1835 frame.shape.green(),
1836 frame.data.as_byte_ptr()
1837 );
1838 let frame = self.evict_tree(frame);
1839 unsafe { frame.drop_and_dealloc_if_needed() };
1840 } else {
1841 let num_fields = sd.fields.len();
1842 trace!(
1843 "De-initializing struct {} at {:p} field-by-field ({} fields)",
1844 frame.shape.yellow(),
1845 frame.data.as_byte_ptr(),
1846 num_fields.to_string().bright_cyan()
1847 );
1848 for i in 0..num_fields {
1849 if frame.istate.fields.has(i) {
1850 let field = sd.fields[i];
1851 let field_shape = field.shape();
1852 let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
1853 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
1854 trace!(
1855 "Recursively cleaning field #{} '{}' of {}: field_shape={}, field_ptr={:p}",
1856 i.to_string().bright_cyan(),
1857 field.name.bright_blue(),
1858 frame.shape.blue(),
1859 field_shape.green(),
1860 field_ptr.as_byte_ptr()
1861 );
1862 let istate = self.istates.remove(&field_id).unwrap();
1863 let field_frame = Frame::recompose(field_id, istate);
1864 to_clean.push(field_frame);
1865 } else {
1866 trace!(
1867 "Field #{} '{}' of {} was NOT initialized, skipping",
1868 i.to_string().bright_cyan(),
1869 sd.fields[i].name.bright_red(),
1870 frame.shape.red()
1871 );
1872 }
1873 }
1874
1875 if frame.istate.mode == FrameMode::Root {
1877 _root_guard = Some(Guard {
1878 ptr: frame.data.as_mut_byte_ptr(),
1879 layout: frame.shape.layout,
1880 });
1881 }
1882 }
1883 }
1884 Def::Enum(_ed) => {
1885 trace!(
1886 "{}",
1887 format!(
1888 "TODO: handle enum deallocation for {} at {:p}",
1889 frame.shape.yellow(),
1890 frame.data.as_byte_ptr()
1891 )
1892 .magenta()
1893 );
1894
1895 if frame.istate.mode == FrameMode::Root {
1897 _root_guard = Some(Guard {
1898 ptr: frame.data.as_mut_byte_ptr(),
1899 layout: frame.shape.layout,
1900 });
1901 }
1902 }
1903 Def::Array(_)
1904 | Def::Slice(_)
1905 | Def::List(_)
1906 | Def::Map(_)
1907 | Def::SmartPointer(_)
1908 | Def::Scalar(_)
1909 | Def::Option(_) => {
1910 trace!(
1911 "Can drop all at once for shape {} (def variant: {:?}, frame mode {:?}) at {:p}",
1912 frame.shape.cyan(),
1913 frame.shape.def,
1914 frame.istate.mode.yellow(),
1915 frame.data.as_byte_ptr(),
1916 );
1917
1918 if frame.is_fully_initialized() {
1919 unsafe { frame.drop_and_dealloc_if_needed() }
1920 } else {
1921 frame.dealloc_if_needed();
1922 }
1923 }
1924 _ => {}
1925 }
1926 }
1927
1928 let mut all_ids = self.istates.keys().copied().collect::<Vec<_>>();
1930 for frame_id in all_ids.drain(..) {
1931 let frame_istate = self.istates.remove(&frame_id).unwrap();
1932
1933 trace!(
1934 "Checking leftover istate: id.shape={} id.ptr={:p} mode={:?}",
1935 frame_id.shape.cyan(),
1936 frame_id.ptr,
1937 frame_istate.mode.yellow()
1938 );
1939 let mut frame = Frame::recompose(frame_id, frame_istate);
1940
1941 if frame.is_fully_initialized() {
1942 trace!("It's fully initialized, we can drop it");
1943 unsafe { frame.drop_and_dealloc_if_needed() };
1944 } else if frame.istate.flags.contains(FrameFlags::ALLOCATED) {
1945 trace!("Not initialized but allocated, let's free it");
1946 frame.dealloc_if_needed();
1947 }
1948 }
1949 }
1950}