rkyv/collections/btree_map/
validation.rs

1//! Validation implementation for BTreeMap.
2
3use super::{
4    ArchivedBTreeMap, ClassifiedNode, InnerNode, InnerNodeEntry, LeafNode, LeafNodeEntry, Node,
5    NodeHeader, MIN_ENTRIES_PER_INNER_NODE, MIN_ENTRIES_PER_LEAF_NODE,
6};
7use crate::{
8    rel_ptr::RelPtr,
9    validation::{ArchiveContext, LayoutRaw},
10    Archived, Fallible,
11};
12use bytecheck::{CheckBytes, Error};
13use core::{
14    alloc::{Layout, LayoutError},
15    convert::{Infallible, TryFrom},
16    fmt,
17    hint::unreachable_unchecked,
18    ptr,
19};
20use ptr_meta::Pointee;
21
22impl<K, C> CheckBytes<C> for InnerNodeEntry<K>
23where
24    K: CheckBytes<C>,
25    C: ArchiveContext + ?Sized,
26    C::Error: Error,
27{
28    type Error = K::Error;
29
30    #[inline]
31    unsafe fn check_bytes<'a>(
32        value: *const Self,
33        context: &mut C,
34    ) -> Result<&'a Self, Self::Error> {
35        RelPtr::manual_check_bytes(ptr::addr_of!((*value).ptr), context)
36            .unwrap_or_else(|_| core::hint::unreachable_unchecked());
37        K::check_bytes(ptr::addr_of!((*value).key), context)?;
38
39        Ok(&*value)
40    }
41}
42
43/// An error that can occur while checking a leaf node entry.
44#[derive(Debug)]
45pub enum LeafNodeEntryError<K, V> {
46    /// An error occurred while checking the entry's key.
47    KeyCheckError(K),
48    /// An error occurred while checking the entry's value.
49    ValueCheckError(V),
50}
51
52impl<K: fmt::Display, V: fmt::Display> fmt::Display for LeafNodeEntryError<K, V> {
53    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54        match self {
55            LeafNodeEntryError::KeyCheckError(e) => write!(f, "key check error: {}", e),
56            LeafNodeEntryError::ValueCheckError(e) => write!(f, "value check error: {}", e),
57        }
58    }
59}
60
61#[cfg(feature = "std")]
62const _: () = {
63    use std::error::Error;
64
65    impl<K: Error + 'static, V: Error + 'static> Error for LeafNodeEntryError<K, V> {
66        fn source(&self) -> Option<&(dyn Error + 'static)> {
67            match self {
68                Self::KeyCheckError(e) => Some(e as &dyn Error),
69                Self::ValueCheckError(e) => Some(e as &dyn Error),
70            }
71        }
72    }
73};
74
75impl<K, V, C> CheckBytes<C> for LeafNodeEntry<K, V>
76where
77    K: CheckBytes<C>,
78    V: CheckBytes<C>,
79    C: Fallible + ?Sized,
80    C::Error: Error,
81{
82    type Error = LeafNodeEntryError<K::Error, V::Error>;
83
84    #[inline]
85    unsafe fn check_bytes<'a>(
86        value: *const Self,
87        context: &mut C,
88    ) -> Result<&'a Self, Self::Error> {
89        K::check_bytes(ptr::addr_of!((*value).key), context)
90            .map_err(LeafNodeEntryError::KeyCheckError)?;
91        V::check_bytes(ptr::addr_of!((*value).value), context)
92            .map_err(LeafNodeEntryError::ValueCheckError)?;
93        Ok(&*value)
94    }
95}
96
97/// Errors that can occur while checking an archived B-tree.
98#[derive(Debug)]
99pub enum ArchivedBTreeMapError<K, V, C> {
100    /// An error occurred while checking the bytes of a key
101    KeyCheckError(K),
102    /// An error occurred while checking the bytes of a value
103    ValueCheckError(V),
104    /// The number of entries in the inner node is less than the minimum number of entries required
105    TooFewInnerNodeEntries(usize),
106    /// The number of entries in the leaf node is less than the minimum number of entries
107    TooFewLeafNodeEntries(usize),
108    /// An error occurred while checking the entries of an inner node
109    CheckInnerNodeEntryError {
110        /// The index of the inner node entry
111        index: usize,
112        /// The inner error that occurred
113        inner: K,
114    },
115    /// An error occurred while checking the entries of a leaf node
116    CheckLeafNodeEntryError {
117        /// The index of the leaf node entry
118        index: usize,
119        /// The inner error that occurred
120        inner: LeafNodeEntryError<K, V>,
121    },
122    /// The size of an inner node was invalid
123    InvalidNodeSize(usize),
124    /// The child of an inner node had a first key that did not match the inner node's key
125    MismatchedInnerChildKey,
126    /// The leaf level of the B-tree contained an inner node
127    InnerNodeInLeafLevel,
128    /// The leaves of the B-tree were not all located at the same depth
129    InvalidLeafNodeDepth {
130        /// The depth of the first leaf node in the tree
131        expected: usize,
132        /// The depth of the invalid leaf node
133        actual: usize,
134    },
135    /// A leaf node did not contain entries in sorted order
136    UnsortedLeafNodeEntries,
137    /// A leaf node is not linked after a node despite being the next leaf node
138    UnlinkedLeafNode,
139    /// A leaf node with lesser keys is linked after a leaf node with greater keys
140    UnsortedLeafNode,
141    /// The forward pointer of the last leaf did not have an offset of 0
142    LastLeafForwardPointerNotNull,
143    /// The number of entries the B-tree claims to have does not match the actual number of entries
144    LengthMismatch {
145        /// The number of entries the B-tree claims to have
146        expected: usize,
147        /// The actual number of entries in the B-tree
148        actual: usize,
149    },
150    /// The keys for an inner node were incorrect
151    IncorrectChildKey,
152    /// An context error occurred
153    ContextError(C),
154}
155
156impl<K, V, C> From<Infallible> for ArchivedBTreeMapError<K, V, C> {
157    fn from(_: Infallible) -> Self {
158        unsafe { core::hint::unreachable_unchecked() }
159    }
160}
161
162impl<K, V, C> fmt::Display for ArchivedBTreeMapError<K, V, C>
163where
164    K: fmt::Display,
165    V: fmt::Display,
166    C: fmt::Display,
167{
168    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
169        match self {
170            Self::KeyCheckError(e) => write!(f, "key check error: {}", e),
171            Self::ValueCheckError(e) => write!(f, "value check error: {}", e),
172            Self::TooFewInnerNodeEntries(n) => write!(
173                f,
174                "too few inner node entries (expected at least {}): {}",
175                MIN_ENTRIES_PER_INNER_NODE, n
176            ),
177            Self::TooFewLeafNodeEntries(n) => write!(
178                f,
179                "too few leaf node entries (expected at least {}): {}",
180                MIN_ENTRIES_PER_LEAF_NODE, n,
181            ),
182            Self::CheckInnerNodeEntryError { index, inner } => write!(
183                f,
184                "inner node entry check error: index {}, error {}",
185                index, inner
186            ),
187            Self::CheckLeafNodeEntryError { index, inner } => write!(
188                f,
189                "leaf node entry check error: index {}, error {}",
190                index, inner
191            ),
192            Self::InvalidNodeSize(n) => write!(f, "invalid node size: {}", n),
193            Self::MismatchedInnerChildKey => write!(f, "mismatched inner child key"),
194            Self::InnerNodeInLeafLevel => write!(f, "inner node in leaf level"),
195            Self::InvalidLeafNodeDepth { expected, actual } => write!(
196                f,
197                "expected leaf node depth {} but found leaf node depth {}",
198                expected, actual,
199            ),
200            Self::UnsortedLeafNodeEntries => write!(f, "leaf node contains keys in unsorted order"),
201            Self::UnlinkedLeafNode => write!(f, "leaf nodes are not linked in the sorted order"),
202            Self::UnsortedLeafNode => write!(f, "leaf nodes are not linked in sorted order"),
203            Self::LastLeafForwardPointerNotNull => {
204                write!(f, "the forward pointer of the last leaf was not null")
205            }
206            Self::LengthMismatch { expected, actual } => write!(
207                f,
208                "expected {} entries but there were actually {} entries",
209                expected, actual,
210            ),
211            Self::IncorrectChildKey => write!(f, "incorrect child key in inner node"),
212            Self::ContextError(e) => write!(f, "context error: {}", e),
213        }
214    }
215}
216
217#[cfg(feature = "std")]
218const _: () = {
219    use std::error::Error;
220
221    impl<K, V, C> Error for ArchivedBTreeMapError<K, V, C>
222    where
223        K: Error + 'static,
224        V: Error + 'static,
225        C: Error + 'static,
226    {
227        fn source(&self) -> Option<&(dyn Error + 'static)> {
228            match self {
229                Self::KeyCheckError(e) => Some(e as &dyn Error),
230                Self::ValueCheckError(e) => Some(e as &dyn Error),
231                Self::TooFewInnerNodeEntries(_) => None,
232                Self::TooFewLeafNodeEntries(_) => None,
233                Self::CheckInnerNodeEntryError { inner, .. } => Some(inner as &dyn Error),
234                Self::CheckLeafNodeEntryError { inner, .. } => Some(inner as &dyn Error),
235                Self::InvalidNodeSize(_) => None,
236                Self::MismatchedInnerChildKey => None,
237                Self::InnerNodeInLeafLevel => None,
238                Self::InvalidLeafNodeDepth { .. } => None,
239                Self::UnsortedLeafNodeEntries => None,
240                Self::UnlinkedLeafNode => None,
241                Self::UnsortedLeafNode => None,
242                Self::LastLeafForwardPointerNotNull => None,
243                Self::LengthMismatch { .. } => None,
244                Self::IncorrectChildKey => None,
245                Self::ContextError(e) => Some(e as &dyn Error),
246            }
247        }
248    }
249};
250
251impl<T> LayoutRaw for Node<[T]> {
252    fn layout_raw(metadata: <Self as Pointee>::Metadata) -> Result<Layout, LayoutError> {
253        let result = Layout::new::<NodeHeader>()
254            .extend(Layout::array::<T>(metadata).unwrap())?
255            .0;
256        #[cfg(not(feature = "strict"))]
257        {
258            Ok(result)
259        }
260        #[cfg(feature = "strict")]
261        {
262            Ok(result.pad_to_align())
263        }
264    }
265}
266
267type ABTMError<K, V, C> = ArchivedBTreeMapError<
268    <K as CheckBytes<C>>::Error,
269    <V as CheckBytes<C>>::Error,
270    <C as Fallible>::Error,
271>;
272
273impl NodeHeader {
274    #[inline]
275    unsafe fn manual_check_bytes<'a, K, V, C>(
276        value: *const Self,
277        context: &mut C,
278    ) -> Result<&'a Self, ABTMError<K, V, C>>
279    where
280        K: CheckBytes<C>,
281        V: CheckBytes<C>,
282        C: ArchiveContext + ?Sized,
283        C::Error: Error,
284    {
285        let raw_node = Self::manual_check_header(value, context)
286            .map_err(ArchivedBTreeMapError::ContextError)?;
287
288        let node_layout = if raw_node.is_inner() {
289            InnerNode::<K>::layout_raw(ptr_meta::metadata(raw_node.classify_inner_ptr::<K>()))
290                .map_err(C::wrap_layout_error)
291                .map_err(ArchivedBTreeMapError::ContextError)?
292        } else {
293            LeafNode::<K, V>::layout_raw(ptr_meta::metadata(raw_node.classify_leaf_ptr::<K, V>()))
294                .map_err(C::wrap_layout_error)
295                .map_err(ArchivedBTreeMapError::ContextError)?
296        };
297
298        context
299            .bounds_check_subtree_ptr_layout((raw_node as *const NodeHeader).cast(), &node_layout)
300            .map_err(ArchivedBTreeMapError::ContextError)?;
301
302        Self::manual_check_contents::<K, V, C>(raw_node, context)?;
303
304        Ok(raw_node)
305    }
306
307    #[inline]
308    unsafe fn manual_check_header<'a, C>(
309        value: *const Self,
310        context: &mut C,
311    ) -> Result<&'a Self, C::Error>
312    where
313        C: ArchiveContext + ?Sized,
314        C::Error: Error,
315    {
316        CheckBytes::check_bytes(ptr::addr_of!((*value).meta), context).map_err(
317            // SAFETY: Infallible cannot exist
318            |_: Infallible| unreachable_unchecked(),
319        )?;
320        CheckBytes::check_bytes(ptr::addr_of!((*value).size), context).map_err(
321            // SAFETY: Infallible cannot exist
322            |_: Infallible| unreachable_unchecked(),
323        )?;
324        RelPtr::manual_check_bytes(ptr::addr_of!((*value).ptr), context).map_err(
325            // SAFETY: Infallible cannot exist
326            |_: Infallible| unreachable_unchecked(),
327        )?;
328
329        // All the fields have been checked and this is a valid RawNode
330        Ok(&*value)
331    }
332
333    #[inline]
334    unsafe fn manual_check_contents<K, V, C>(
335        raw_node: &Self,
336        context: &mut C,
337    ) -> Result<(), ABTMError<K, V, C>>
338    where
339        K: CheckBytes<C>,
340        V: CheckBytes<C>,
341        C: ArchiveContext + ?Sized,
342        C::Error: Error,
343    {
344        // Now that the fields have been checked, we can start checking the specific subtype
345        let root = (raw_node as *const Self).cast();
346        let size = from_archived!(raw_node.size) as usize;
347        let offset =
348            -isize::try_from(size).map_err(|_| ArchivedBTreeMapError::InvalidNodeSize(size))?;
349        let start = context
350            .check_ptr(root, offset, ())
351            .map_err(ArchivedBTreeMapError::ContextError)?;
352
353        // Push a new suffix range and check the inner or leaf part
354        let range = context
355            .push_suffix_subtree_range(start, root)
356            .map_err(ArchivedBTreeMapError::ContextError)?;
357        if raw_node.is_inner() {
358            InnerNode::manual_check_bytes::<V, C>(raw_node.classify_inner_ptr::<K>(), context)?;
359        } else {
360            CheckBytes::check_bytes(raw_node.classify_leaf_ptr::<K, V>(), context)?;
361        }
362        context
363            .pop_suffix_range(range)
364            .map_err(ArchivedBTreeMapError::ContextError)?;
365
366        Ok(())
367    }
368}
369
370impl<K> InnerNode<K> {
371    #[allow(clippy::type_complexity)]
372    fn verify_integrity<'a, V, C>(
373        &'a self,
374    ) -> Result<&K, ArchivedBTreeMapError<K::Error, V::Error, C::Error>>
375    where
376        K: CheckBytes<C> + PartialEq,
377        V: CheckBytes<C> + 'a,
378        C: Fallible + ?Sized,
379    {
380        for entry in self.tail.iter() {
381            let child = unsafe { &*entry.ptr.as_ptr() }.classify::<K, V>();
382            let first_key = match child {
383                ClassifiedNode::Inner(c) => c.verify_integrity::<V, C>()?,
384                ClassifiedNode::Leaf(c) => &c.tail[0].key,
385            };
386            if !entry.key.eq(first_key) {
387                return Err(ArchivedBTreeMapError::IncorrectChildKey);
388            }
389        }
390
391        let least_child = unsafe { &*self.header.ptr.as_ptr() }.classify::<K, V>();
392        let first_key = match least_child {
393            ClassifiedNode::Inner(c) => c.verify_integrity::<V, C>()?,
394            ClassifiedNode::Leaf(c) => &c.tail[0].key,
395        };
396
397        Ok(first_key)
398    }
399
400    #[inline]
401    unsafe fn manual_check_bytes<'a, V, C>(
402        value: *const Self,
403        context: &mut C,
404    ) -> Result<&'a Self, ABTMError<K, V, C>>
405    where
406        K: CheckBytes<C>,
407        V: CheckBytes<C>,
408        C: ArchiveContext + ?Sized,
409        C::Error: Error,
410    {
411        // meta, size, and ptr have already been checked by the check_bytes for RawNode
412        let len = ptr_meta::metadata(value);
413
414        // Each inner node actually contains one more entry that the length indicates (the least
415        // child pointer)
416        if len + 1 < MIN_ENTRIES_PER_INNER_NODE {
417            return Err(ArchivedBTreeMapError::TooFewInnerNodeEntries(len + 1));
418        }
419
420        // The subtree range has already been set up for us so we can just check our tail
421        let tail_ptr = ptr::addr_of!((*value).tail) as *const InnerNodeEntry<K>;
422        for index in (0..len).rev() {
423            CheckBytes::check_bytes(tail_ptr.add(index), context).map_err(|inner| {
424                ArchivedBTreeMapError::CheckInnerNodeEntryError { index, inner }
425            })?;
426        }
427
428        Ok(&*value)
429    }
430}
431
432impl<K, V, C> CheckBytes<C> for LeafNode<K, V>
433where
434    K: CheckBytes<C>,
435    V: CheckBytes<C>,
436    C: ArchiveContext + ?Sized,
437    C::Error: Error,
438{
439    type Error = ArchivedBTreeMapError<K::Error, V::Error, C::Error>;
440
441    #[inline]
442    unsafe fn check_bytes<'a>(
443        value: *const Self,
444        context: &mut C,
445    ) -> Result<&'a Self, Self::Error> {
446        // meta, size, and ptr have already been checked by the check_bytes for RawNode
447        let len = ptr_meta::metadata(value);
448
449        if len < MIN_ENTRIES_PER_LEAF_NODE {
450            return Err(ArchivedBTreeMapError::TooFewLeafNodeEntries(len));
451        }
452
453        // The subtree range has already been set up for us so we can just check our tail
454        let tail_ptr = ptr::addr_of!((*value).tail) as *const LeafNodeEntry<K, V>;
455        for index in (0..len).rev() {
456            CheckBytes::check_bytes(tail_ptr.add(index), context)
457                .map_err(|inner| ArchivedBTreeMapError::CheckLeafNodeEntryError { index, inner })?;
458        }
459
460        Ok(&*value)
461    }
462}
463
464#[cfg(feature = "alloc")]
465const _: () = {
466    #[cfg(not(feature = "std"))]
467    use alloc::collections::VecDeque;
468    #[cfg(feature = "std")]
469    use std::collections::VecDeque;
470
471    impl<K, V, C> CheckBytes<C> for ArchivedBTreeMap<K, V>
472    where
473        K: CheckBytes<C> + Ord,
474        V: CheckBytes<C>,
475        C: ArchiveContext + ?Sized,
476        C::Error: Error,
477    {
478        type Error = ArchivedBTreeMapError<K::Error, V::Error, C::Error>;
479
480        unsafe fn check_bytes<'a>(
481            value: *const Self,
482            context: &mut C,
483        ) -> Result<&'a Self, Self::Error> {
484            let len = from_archived!(*Archived::<usize>::check_bytes(
485                ptr::addr_of!((*value).len),
486                context,
487            )?) as usize;
488
489            if len > 0 {
490                let root_rel_ptr =
491                    RelPtr::manual_check_bytes(ptr::addr_of!((*value).root), context)?;
492
493                // Walk all the inner nodes, claim their memory, and check their contents
494                let mut nodes = VecDeque::new();
495                let root_ptr = context
496                    .check_subtree_rel_ptr(root_rel_ptr)
497                    .map_err(ArchivedBTreeMapError::ContextError)?;
498
499                // Before checking all the nodes, we have to push an additional prefix subtree with
500                // the root node
501                // Otherwise, when the suffix subtree of the root node is popped it will remove any
502                // trailing suffix space that should be checked by subsequent fields
503                let root = NodeHeader::manual_check_header(root_ptr, context)
504                    .map_err(ArchivedBTreeMapError::ContextError)?;
505
506                // To push the subtree, we need to know the real size of the root node
507                // Since the header is checked, we can just classify the pointer and use layout_raw
508                let root_layout = if root.is_inner() {
509                    InnerNode::<K>::layout_raw(ptr_meta::metadata(root.classify_inner_ptr::<K>()))
510                        .map_err(C::wrap_layout_error)
511                        .map_err(ArchivedBTreeMapError::ContextError)?
512                } else {
513                    LeafNode::<K, V>::layout_raw(ptr_meta::metadata(
514                        root.classify_leaf_ptr::<K, V>(),
515                    ))
516                    .map_err(C::wrap_layout_error)
517                    .map_err(ArchivedBTreeMapError::ContextError)?
518                };
519
520                // Because the layout of the subtree is dynamic, we need to bounds check the layout
521                // declared by the root node.
522                context
523                    .bounds_check_subtree_ptr_layout(root_ptr.cast(), &root_layout)
524                    .map_err(ArchivedBTreeMapError::ContextError)?;
525
526                // Now we can push the prefix subtree range.
527                let nodes_range = context
528                    .push_prefix_subtree_range(
529                        root_ptr.cast(),
530                        root_ptr.cast::<u8>().add(root_layout.size()),
531                    )
532                    .map_err(ArchivedBTreeMapError::ContextError)?;
533
534                // Now we're finally ready to check node subtrees
535                NodeHeader::manual_check_contents::<K, V, C>(root, context)?;
536
537                nodes.push_back((root, 0));
538
539                while let Some(&(node, depth)) = nodes.front() {
540                    // Break when a leaf is found
541                    if !node.is_inner() {
542                        break;
543                    }
544                    nodes.pop_front();
545                    let inner = node.classify_inner::<K>();
546
547                    let child_ptr = context
548                        .check_subtree_rel_ptr(&inner.header.ptr)
549                        .map_err(ArchivedBTreeMapError::ContextError)?;
550                    let child = NodeHeader::manual_check_bytes::<K, V, C>(child_ptr, context)?;
551                    nodes.push_back((child, depth + 1));
552
553                    // The invariant that this node contains keys less than the first key of this node will
554                    // be checked when we iterate through the leaf nodes in order and check ordering
555                    for entry in inner.tail.iter() {
556                        let child_ptr = context
557                            .check_subtree_rel_ptr(&entry.ptr)
558                            .map_err(ArchivedBTreeMapError::ContextError)?;
559                        let child = NodeHeader::manual_check_bytes::<K, V, C>(child_ptr, context)?;
560                        nodes.push_back((child, depth + 1));
561                    }
562                }
563
564                // We're done checking node subtrees now
565                context
566                    .pop_prefix_range(nodes_range)
567                    .map_err(ArchivedBTreeMapError::ContextError)?;
568
569                // The remaining nodes must all be leaf nodes
570                let mut entry_count = 0;
571                for (node, depth) in nodes.iter() {
572                    if !node.is_leaf() {
573                        return Err(ArchivedBTreeMapError::InnerNodeInLeafLevel);
574                    }
575                    let leaf = node.classify_leaf::<K, V>();
576
577                    // Leaf nodes must all be the same depth
578                    let expected_depth = nodes.front().unwrap().1;
579                    if *depth != expected_depth {
580                        return Err(ArchivedBTreeMapError::InvalidLeafNodeDepth {
581                            expected: expected_depth,
582                            actual: *depth,
583                        });
584                    }
585
586                    // They must contain entries in sorted order
587                    for (prev, next) in leaf.tail.iter().zip(leaf.tail.iter().skip(1)) {
588                        if next.key < prev.key {
589                            return Err(ArchivedBTreeMapError::UnsortedLeafNodeEntries);
590                        }
591                    }
592
593                    // Keep track of the number of entries found
594                    entry_count += leaf.tail.len();
595                }
596
597                for (i, (node, _)) in nodes.iter().enumerate() {
598                    let leaf = node.classify_leaf::<K, V>();
599
600                    // And they must link together in sorted order
601                    if i < nodes.len() - 1 {
602                        let next_ptr = context
603                            .check_rel_ptr(&leaf.header.ptr)
604                            .map_err(ArchivedBTreeMapError::ContextError)?;
605                        let next_node = nodes[i + 1].0.classify_leaf();
606
607                        if next_ptr != (next_node as *const LeafNode<K, V>).cast() {
608                            return Err(ArchivedBTreeMapError::UnlinkedLeafNode);
609                        }
610                        if next_node.tail[0].key < leaf.tail[leaf.tail.len() - 1].key {
611                            return Err(ArchivedBTreeMapError::UnsortedLeafNode);
612                        }
613                    } else {
614                        // The last node must have a null pointer forward
615                        if !leaf.header.ptr.is_null() {
616                            return Err(ArchivedBTreeMapError::LastLeafForwardPointerNotNull);
617                        }
618                    }
619                }
620
621                // Make sure that the number of entries matches the length
622                if entry_count != len {
623                    return Err(ArchivedBTreeMapError::LengthMismatch {
624                        expected: len,
625                        actual: entry_count,
626                    });
627                }
628
629                // Make sure that inner nodes are constructed appropriately
630                if root.is_inner() {
631                    root.classify_inner::<K>().verify_integrity::<V, C>()?;
632                }
633            }
634
635            Ok(&*value)
636        }
637    }
638};