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 owo_colors::OwoColorize;
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 let Def::Option(option_def) = option_shape.def else {
1188 return Err(ReflectError::WasNotA {
1189 expected: "option",
1190 actual: option_shape,
1191 });
1192 };
1193
1194 let inner_shape = option_def.t();
1196
1197 let inner_data = inner_shape.allocate();
1199
1200 let mut inner_frame = Frame {
1202 data: inner_data,
1203 shape: inner_shape,
1204 field_index_in_parent: None,
1206 istate: IState::new(
1207 self.frames.len(),
1208 FrameMode::OptionSome,
1209 FrameFlags::ALLOCATED,
1211 ),
1212 };
1213
1214 trace!(
1215 "[{}] Pushing option frame for {}",
1216 self.frames.len(),
1217 option_shape.blue(),
1218 );
1219
1220 if let Some(iset) = self.istates.remove(&inner_frame.id()) {
1221 trace!(
1222 "[{}] Restoring saved state for {}",
1223 self.frames.len(),
1224 inner_frame.id().shape.blue()
1225 );
1226 inner_frame.istate = iset;
1227 }
1228
1229 self.frames.push(inner_frame);
1230 Ok(self)
1231 }
1232
1233 pub fn pop_some_push_none(mut self) -> Result<Self, ReflectError> {
1243 let Some(frame) = self.frames.last_mut() else {
1245 return Err(ReflectError::OperationFailed {
1246 shape: <()>::SHAPE,
1247 operation: "tried to pop_some_push_none but there was no frame",
1248 });
1249 };
1250
1251 if frame.istate.mode != FrameMode::OptionSome {
1253 return Err(ReflectError::OperationFailed {
1254 shape: frame.shape,
1255 operation: "pop_some_push_none called, but frame was not in Option mode",
1256 });
1257 }
1258
1259 if frame.is_fully_initialized() {
1261 return Err(ReflectError::OperationFailed {
1262 shape: frame.shape,
1263 operation: "option frame already initialized, cannot pop_some_push_none",
1264 });
1265 }
1266
1267 frame.dealloc_if_needed();
1268
1269 let _frame = self.frames.pop().expect("frame already checked");
1271
1272 let parent_frame = self
1274 .frames
1275 .last_mut()
1276 .ok_or(ReflectError::OperationFailed {
1277 shape: <()>::SHAPE,
1278 operation: "tried to pop_some_push_none but there was no parent frame",
1279 })?;
1280
1281 unsafe {
1283 if let Some(default_fn) = parent_frame.shape.vtable.default_in_place {
1284 default_fn(parent_frame.data);
1285 } else {
1286 return Err(ReflectError::OperationFailed {
1287 shape: parent_frame.shape,
1288 operation: "option type does not implement Default",
1289 });
1290 }
1291 parent_frame.mark_fully_initialized();
1292 }
1293
1294 let Def::Option(od) = parent_frame.shape.def else {
1295 return Err(ReflectError::OperationFailed {
1296 shape: parent_frame.shape,
1297 operation: "pop_some_push_none and the parent isn't of type Option???",
1298 });
1299 };
1300
1301 let data = parent_frame.data;
1303
1304 let mut frame = Frame {
1305 data,
1306 shape: od.t(),
1307 field_index_in_parent: Some(0),
1308 istate: IState::new(self.frames.len(), FrameMode::OptionNone, FrameFlags::EMPTY),
1309 };
1310 unsafe {
1311 frame.mark_fully_initialized();
1312 }
1313
1314 self.frames.push(frame);
1315
1316 Ok(self)
1317 }
1318
1319 pub fn push_map_key(mut self) -> Result<Self, ReflectError> {
1324 let frame = self.frames.last().unwrap();
1326 let map_shape = frame.shape;
1327
1328 if !matches!(map_shape.def, Def::Map(_)) {
1329 return Err(ReflectError::WasNotA {
1330 expected: "map or hash map",
1331 actual: map_shape,
1332 });
1333 }
1334
1335 if !frame.istate.fields.has(0) {
1337 self = self.begin_map_insert()?;
1338 }
1339
1340 let key_shape = self.key_shape()?;
1342
1343 let key_data = key_shape.allocate();
1345
1346 let mut key_frame = Frame {
1348 data: key_data,
1349 shape: key_shape,
1350 field_index_in_parent: None,
1351 istate: IState::new(self.frames.len(), FrameMode::MapKey, FrameFlags::ALLOCATED),
1352 };
1353
1354 trace!(
1355 "[{}] Pushing key of type {} for map {}",
1356 self.frames.len(),
1357 key_shape.green(),
1358 map_shape.blue(),
1359 );
1360
1361 if let Some(iset) = self.istates.remove(&key_frame.id()) {
1362 trace!(
1363 "[{}] Restoring saved state for {}",
1364 self.frames.len(),
1365 key_frame.id().shape.blue()
1366 );
1367 key_frame.istate = iset;
1368 }
1369
1370 self.frames.push(key_frame);
1371 Ok(self)
1372 }
1373
1374 pub fn push_map_value(mut self) -> Result<Self, ReflectError> {
1379 trace!("Wants to push map value. Frames = ");
1380 for (i, f) in self.frames.iter().enumerate() {
1381 trace!("Frame {}: {:?}", i, f);
1382 }
1383
1384 if self.frames.len() < 2 {
1386 return Err(ReflectError::OperationFailed {
1387 shape: <()>::SHAPE,
1388 operation: "tried to push map value but there was no key frame",
1389 });
1390 }
1391
1392 let key_frame_index = self.frames.len() - 1;
1394 let key_frame = &self.frames[key_frame_index];
1395
1396 match key_frame.istate.mode {
1398 FrameMode::MapKey => {} _ => {
1400 return Err(ReflectError::OperationFailed {
1401 shape: key_frame.shape,
1402 operation: "current frame is not a map key",
1403 });
1404 }
1405 }
1406
1407 if !key_frame.is_fully_initialized() {
1409 return Err(ReflectError::OperationFailed {
1410 shape: key_frame.shape,
1411 operation: "map key is not fully initialized",
1412 });
1413 }
1414
1415 let map_frame_index = self.frames.len() - 2;
1417 let map_frame = &self.frames[map_frame_index];
1418 let map_shape = map_frame.shape;
1419
1420 let Def::Map(map_def) = map_shape.def else {
1421 return Err(ReflectError::WasNotA {
1422 expected: "map",
1423 actual: map_frame.shape,
1424 });
1425 };
1426
1427 let value_shape = map_def.v;
1428
1429 let value_data = value_shape.allocate();
1431
1432 let mut value_frame = Frame {
1434 data: value_data,
1435 shape: value_shape,
1436 field_index_in_parent: None,
1437 istate: IState::new(
1438 self.frames.len(),
1439 FrameMode::MapValue {
1440 index: key_frame_index,
1441 },
1442 FrameFlags::ALLOCATED,
1443 ),
1444 };
1445
1446 trace!(
1447 "[{}] Pushing value of type {} for map {} with key type {}",
1448 self.frames.len(),
1449 value_shape.green(),
1450 map_shape.blue(),
1451 key_frame.shape.yellow(),
1452 );
1453
1454 if let Some(iset) = self.istates.remove(&value_frame.id()) {
1455 trace!(
1456 "[{}] Restoring saved state for {}",
1457 self.frames.len(),
1458 value_frame.id().shape.blue()
1459 );
1460 value_frame.istate = iset;
1461 }
1462
1463 self.frames.push(value_frame);
1464 Ok(self)
1465 }
1466
1467 pub fn pop(mut self) -> Result<Self, ReflectError> {
1469 let Some(frame) = self.pop_inner() else {
1470 return Err(ReflectError::InvariantViolation {
1471 invariant: "No frame to pop",
1472 });
1473 };
1474 self.track(frame);
1475 Ok(self)
1476 }
1477
1478 fn pop_inner(&mut self) -> Option<Frame> {
1479 let mut frame = self.frames.pop()?;
1480 let frame_shape = frame.shape;
1481
1482 let init = frame.is_fully_initialized();
1483 trace!(
1484 "[{}] {} popped, {} initialized",
1485 self.frames.len(),
1486 frame_shape.blue(),
1487 if init {
1488 "✅ fully".style(owo_colors::Style::new().green())
1489 } else {
1490 "🚧 partially".style(owo_colors::Style::new().red())
1491 }
1492 );
1493 if init {
1494 if let Some(parent) = self.frames.last_mut() {
1495 if let Some(index) = frame.field_index_in_parent {
1496 parent.istate.fields.set(index);
1497 }
1498 }
1499 }
1500
1501 match frame.istate.mode {
1503 FrameMode::ListElement => {
1505 if frame.is_fully_initialized() {
1506 let frame_len = self.frames.len();
1509
1510 let parent_frame = self.frames.last_mut().unwrap();
1512 let parent_shape = parent_frame.shape;
1513
1514 match parent_shape.def {
1516 Def::List(_) => {
1517 if let Def::List(list_def) = parent_shape.def {
1519 let list_vtable = list_def.vtable;
1520 trace!(
1521 "[{}] Pushing element to list {}",
1522 frame_len,
1523 parent_shape.blue()
1524 );
1525 unsafe {
1526 (list_vtable.push)(
1528 PtrMut::new(parent_frame.data.as_mut_byte_ptr()),
1529 PtrMut::new(frame.data.as_mut_byte_ptr()),
1530 );
1531 frame.mark_moved_out_of();
1532 }
1533 } else {
1534 panic!("parent frame is not a list type");
1535 }
1536 }
1537 _ => {
1538 panic!("Expected list or array, got {}", frame.shape);
1539 }
1540 }
1541 }
1542 }
1543
1544 FrameMode::MapValue {
1546 index: key_frame_index,
1547 } if frame.is_fully_initialized() => {
1548 let mut key_frame = self.frames.remove(key_frame_index);
1552
1553 if !key_frame.istate.fields.is_any_set() {
1555 panic!("key is not initialized when popping value frame");
1556 }
1557
1558 let frame_len = self.frames.len();
1560 let parent_frame = self.frames.last_mut().unwrap();
1561 let parent_shape = parent_frame.shape;
1562
1563 match parent_shape.def {
1565 Def::Map(_) => {
1566 if let Def::Map(map_def) = parent_shape.def {
1568 trace!(
1569 "[{}] Inserting key-value pair into map {}",
1570 frame_len,
1571 parent_shape.blue()
1572 );
1573 unsafe {
1574 (map_def.vtable.insert_fn)(
1576 parent_frame.data.assume_init(),
1577 key_frame.data.assume_init(),
1578 PtrMut::new(frame.data.as_mut_byte_ptr()),
1579 );
1580 key_frame.mark_moved_out_of();
1581 frame.mark_moved_out_of();
1582 }
1583 } else {
1584 panic!("parent frame is not a map type");
1585 }
1586 }
1587 _ => {
1588 panic!("Expected map or hash map, got {}", frame.shape);
1589 }
1590 }
1591 }
1592
1593 FrameMode::OptionSome => {
1595 if frame.is_fully_initialized() {
1596 trace!("Popping OptionSome (fully init'd)");
1597
1598 let frame_len = self.frames.len();
1600
1601 let parent_frame = self.frames.last_mut().unwrap();
1603 let parent_shape = parent_frame.shape;
1604
1605 match parent_shape.def {
1607 Def::Option(option_def) => {
1608 trace!(
1609 "[{}] Setting Some value in option {}",
1610 frame_len,
1611 parent_shape.blue()
1612 );
1613 unsafe {
1614 (option_def.vtable.init_some_fn)(
1616 parent_frame.data,
1617 PtrConst::new(frame.data.as_byte_ptr()),
1618 );
1619 trace!("Marking parent frame as fully initialized");
1620 parent_frame.mark_fully_initialized();
1621
1622 frame.mark_moved_out_of();
1623 }
1624 }
1625 _ => {
1626 panic!(
1627 "Expected parent frame to be an option type, got {}",
1628 frame.shape
1629 );
1630 }
1631 }
1632 } else {
1633 trace!("Popping OptionSome (not fully init'd)");
1634 }
1635 }
1636
1637 FrameMode::MapKey => {}
1640
1641 FrameMode::Normal => {}
1643
1644 _ => {}
1646 }
1647
1648 Some(frame)
1649 }
1650
1651 pub fn evict_tree(&mut self, frame: Frame) -> Frame {
1655 match frame.shape.def {
1656 Def::Struct(sd) => {
1657 for f in sd.fields {
1658 let id = ValueId {
1659 shape: f.shape(),
1660 ptr: unsafe { frame.data.field_uninit_at(f.offset) }.as_byte_ptr(),
1661 };
1662 if let Some(istate) = self.istates.remove(&id) {
1663 let frame = Frame::recompose(id, istate);
1664 self.evict_tree(frame);
1665 } else {
1666 trace!("No istate found for field {}", f.name);
1667 }
1668 }
1669 }
1670 Def::Enum(_ed) => {
1671 if let Some(variant) = &frame.istate.variant {
1673 trace!(
1674 "Evicting enum {} variant '{}' fields",
1675 frame.shape.blue(),
1676 variant.name.yellow()
1677 );
1678 for field in variant.data.fields {
1680 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
1682 let field_shape = field.shape();
1683 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
1684
1685 if let Some(field_istate) = self.istates.remove(&field_id) {
1687 trace!(
1688 "Evicting field '{}' (shape {}) of enum variant '{}'",
1689 field.name.bright_blue(),
1690 field_shape.green(),
1691 variant.name.yellow()
1692 );
1693 let field_frame = Frame::recompose(field_id, field_istate);
1695 self.evict_tree(field_frame);
1697 } else {
1698 trace!(
1699 "Field '{}' (shape {}) of enum variant '{}' not found in istates, skipping eviction",
1700 field.name.red(),
1701 field_shape.red(),
1702 variant.name.yellow()
1703 );
1704 }
1705 }
1706 } else {
1707 trace!(
1709 "Enum {} has no variant selected, no fields to evict.",
1710 frame.shape.blue()
1711 );
1712 }
1713 }
1714 _ => {}
1715 }
1716 frame
1717 }
1718
1719 #[allow(rustdoc::broken_intra_doc_links)]
1720 pub fn path(&self) -> String {
1723 let mut path = String::from("$");
1724
1725 for (i, frame) in self.frames.iter().enumerate() {
1726 if i == 0 {
1728 continue;
1729 }
1730
1731 match frame.istate.mode {
1732 FrameMode::ListElement => {
1733 if let Some(index) = frame.istate.list_index {
1735 path.push_str(&format!("[{}]", index));
1736 } else {
1737 path.push_str("[?]");
1738 }
1739 }
1740 FrameMode::MapKey => {
1741 path.push_str(".key");
1742 }
1743 FrameMode::MapValue { index: _ } => {
1744 path.push_str(".value");
1745 }
1746 FrameMode::OptionSome => {
1747 path.push_str(".some");
1748 }
1749 FrameMode::OptionNone => {
1750 path.push_str(".none");
1751 }
1752 FrameMode::Root => {
1753 }
1755 FrameMode::Normal => {
1756 if let Some(index) = frame.field_index_in_parent {
1758 if let Some(parent) = self.frames.get(i - 1) {
1760 if let Def::Struct(sd) = parent.shape.def {
1761 if index < sd.fields.len() {
1762 let field_name = sd.fields[index].name;
1763 path.push('.');
1764 path.push_str(field_name);
1765 }
1766 } else if let Def::Enum(_) = parent.shape.def {
1767 if let Some(variant) = &parent.istate.variant {
1768 if index < variant.data.fields.len() {
1769 let field_name = variant.data.fields[index].name;
1770 path.push('.');
1771 path.push_str(field_name);
1772 }
1773 }
1774 }
1775 }
1776 }
1777 }
1778 }
1779 }
1780
1781 path
1782 }
1783}
1784
1785impl Drop for Wip<'_> {
1786 fn drop(&mut self) {
1787 while let Some(frame) = self.frames.pop() {
1788 self.track(frame);
1789 }
1790 trace!("🧹 Whole WIP is dropping",);
1791
1792 let Some((root_id, _)) = self.istates.iter().find(|(_k, istate)| istate.depth == 0) else {
1793 trace!("No root found, we probably built already");
1794 return;
1795 };
1796
1797 let root_id = *root_id;
1798 let root_istate = self.istates.remove(&root_id).unwrap();
1799 let root = Frame::recompose(root_id, root_istate);
1800 let mut to_clean = vec![root];
1801
1802 let mut _root_guard: Option<Guard> = None;
1803
1804 while let Some(mut frame) = to_clean.pop() {
1805 trace!(
1806 "Cleaning frame: shape={} at {:p}, flags={:?}, mode={:?}, fully_initialized={}",
1807 frame.shape.blue(),
1808 frame.data.as_byte_ptr(),
1809 frame.istate.flags.bright_magenta(),
1810 frame.istate.mode.yellow(),
1811 if frame.is_fully_initialized() {
1812 "✅"
1813 } else {
1814 "❌"
1815 }
1816 );
1817
1818 if frame.istate.flags.contains(FrameFlags::MOVED) {
1819 trace!(
1820 "{}",
1821 "Frame was moved out of, nothing to dealloc/drop_in_place".yellow()
1822 );
1823 continue;
1824 }
1825
1826 match frame.shape.def {
1827 Def::Struct(sd) => {
1828 if frame.is_fully_initialized() {
1829 trace!(
1830 "Dropping fully initialized struct: {} at {:p}",
1831 frame.shape.green(),
1832 frame.data.as_byte_ptr()
1833 );
1834 let frame = self.evict_tree(frame);
1835 unsafe { frame.drop_and_dealloc_if_needed() };
1836 } else {
1837 let num_fields = sd.fields.len();
1838 trace!(
1839 "De-initializing struct {} at {:p} field-by-field ({} fields)",
1840 frame.shape.yellow(),
1841 frame.data.as_byte_ptr(),
1842 num_fields.to_string().bright_cyan()
1843 );
1844 for i in 0..num_fields {
1845 if frame.istate.fields.has(i) {
1846 let field = sd.fields[i];
1847 let field_shape = field.shape();
1848 let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
1849 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
1850 trace!(
1851 "Recursively cleaning field #{} '{}' of {}: field_shape={}, field_ptr={:p}",
1852 i.to_string().bright_cyan(),
1853 field.name.bright_blue(),
1854 frame.shape.blue(),
1855 field_shape.green(),
1856 field_ptr.as_byte_ptr()
1857 );
1858 let istate = self.istates.remove(&field_id).unwrap();
1859 let field_frame = Frame::recompose(field_id, istate);
1860 to_clean.push(field_frame);
1861 } else {
1862 trace!(
1863 "Field #{} '{}' of {} was NOT initialized, skipping",
1864 i.to_string().bright_cyan(),
1865 sd.fields[i].name.bright_red(),
1866 frame.shape.red()
1867 );
1868 }
1869 }
1870
1871 if frame.istate.mode == FrameMode::Root {
1873 _root_guard = Some(Guard {
1874 ptr: frame.data.as_mut_byte_ptr(),
1875 layout: frame.shape.layout,
1876 });
1877 }
1878 }
1879 }
1880 Def::Enum(_ed) => {
1881 trace!(
1882 "{}",
1883 format!(
1884 "TODO: handle enum deallocation for {} at {:p}",
1885 frame.shape.yellow(),
1886 frame.data.as_byte_ptr()
1887 )
1888 .magenta()
1889 );
1890
1891 if frame.istate.mode == FrameMode::Root {
1893 _root_guard = Some(Guard {
1894 ptr: frame.data.as_mut_byte_ptr(),
1895 layout: frame.shape.layout,
1896 });
1897 }
1898 }
1899 Def::Array(_)
1900 | Def::Slice(_)
1901 | Def::List(_)
1902 | Def::Map(_)
1903 | Def::SmartPointer(_)
1904 | Def::Scalar(_)
1905 | Def::Option(_) => {
1906 trace!(
1907 "Can drop all at once for shape {} (def variant: {:?}, frame mode {:?}) at {:p}",
1908 frame.shape.cyan(),
1909 frame.shape.def,
1910 frame.istate.mode.yellow(),
1911 frame.data.as_byte_ptr(),
1912 );
1913
1914 if frame.is_fully_initialized() {
1915 unsafe { frame.drop_and_dealloc_if_needed() }
1916 } else {
1917 frame.dealloc_if_needed();
1918 }
1919 }
1920 _ => {}
1921 }
1922 }
1923
1924 let mut all_ids = self.istates.keys().copied().collect::<Vec<_>>();
1926 for frame_id in all_ids.drain(..) {
1927 let frame_istate = self.istates.remove(&frame_id).unwrap();
1928
1929 trace!(
1930 "Checking leftover istate: id.shape={} id.ptr={:p} mode={:?}",
1931 frame_id.shape.cyan(),
1932 frame_id.ptr,
1933 frame_istate.mode.yellow()
1934 );
1935 let mut frame = Frame::recompose(frame_id, frame_istate);
1936
1937 if frame.is_fully_initialized() {
1938 trace!("It's fully initialized, we can drop it");
1939 unsafe { frame.drop_and_dealloc_if_needed() };
1940 } else if frame.istate.flags.contains(FrameFlags::ALLOCATED) {
1941 trace!("Not initialized but allocated, let's free it");
1942 frame.dealloc_if_needed();
1943 }
1944 }
1945 }
1946}