]> git.lizzy.rs Git - rust.git/blob - library/core/src/asserting.rs
Rollup merge of #95005 - ssomers:btree_static_assert, r=thomcc
[rust.git] / library / core / src / asserting.rs
1 // Contains the machinery necessary to print useful `assert!` messages. Not intended for public
2 // usage, not even nightly use-cases.
3 //
4 // Based on https://github.com/dtolnay/case-studies/tree/master/autoref-specialization. When
5 // 'specialization' is robust enough (5 years? 10 years? Never?), `Capture` can be specialized
6 // to [Printable].
7
8 #![allow(missing_debug_implementations)]
9 #![doc(hidden)]
10 #![unstable(feature = "generic_assert_internals", issue = "44838")]
11
12 use crate::{
13     fmt::{Debug, Formatter},
14     marker::PhantomData,
15 };
16
17 // ***** TryCapture - Generic *****
18
19 /// Marker used by [Capture]
20 #[unstable(feature = "generic_assert_internals", issue = "44838")]
21 pub struct TryCaptureWithoutDebug;
22
23 /// Catches an arbitrary `E` and modifies `to` accordingly
24 #[unstable(feature = "generic_assert_internals", issue = "44838")]
25 pub trait TryCaptureGeneric<E, M> {
26     /// Similar to [TryCapturePrintable] but generic to any `E`.
27     fn try_capture(&self, to: &mut Capture<E, M>);
28 }
29
30 impl<E> TryCaptureGeneric<E, TryCaptureWithoutDebug> for &Wrapper<&E> {
31     #[inline]
32     fn try_capture(&self, _: &mut Capture<E, TryCaptureWithoutDebug>) {}
33 }
34
35 impl<E> Debug for Capture<E, TryCaptureWithoutDebug> {
36     fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> {
37         f.write_str("N/A")
38     }
39 }
40
41 // ***** TryCapture - Printable *****
42
43 /// Marker used by [Capture]
44 #[unstable(feature = "generic_assert_internals", issue = "44838")]
45 pub struct TryCaptureWithDebug;
46
47 /// Catches an arbitrary `E: Printable` and modifies `to` accordingly
48 #[unstable(feature = "generic_assert_internals", issue = "44838")]
49 pub trait TryCapturePrintable<E, M> {
50     /// Similar as [TryCaptureGeneric] but specialized to any `E: Printable`.
51     fn try_capture(&self, to: &mut Capture<E, M>);
52 }
53
54 impl<E> TryCapturePrintable<E, TryCaptureWithDebug> for Wrapper<&E>
55 where
56     E: Printable,
57 {
58     #[inline]
59     fn try_capture(&self, to: &mut Capture<E, TryCaptureWithDebug>) {
60         to.elem = Some(*self.0);
61     }
62 }
63
64 impl<E> Debug for Capture<E, TryCaptureWithDebug>
65 where
66     E: Printable,
67 {
68     fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> {
69         match self.elem {
70             None => f.write_str("N/A"),
71             Some(ref value) => Debug::fmt(value, f),
72         }
73     }
74 }
75
76 // ***** Others *****
77
78 /// All possible captured `assert!` elements
79 ///
80 /// # Types
81 ///
82 /// * `E`: **E**lement that is going to be displayed.
83 /// * `M`: **M**arker used to differentiate [Capture]s in regards to [Debug].
84 #[unstable(feature = "generic_assert_internals", issue = "44838")]
85 pub struct Capture<E, M> {
86     // If None, then `E` does not implements [Printable] or `E` wasn't evaluated (`assert!( ... )`
87     // short-circuited).
88     //
89     // If Some, then `E` implements [Printable] and was evaluated.
90     pub elem: Option<E>,
91     phantom: PhantomData<M>,
92 }
93
94 impl<M, T> Capture<M, T> {
95     #[inline]
96     pub const fn new() -> Self {
97         Self { elem: None, phantom: PhantomData }
98     }
99 }
100
101 /// Necessary for the implementations of `TryCapture*`
102 #[unstable(feature = "generic_assert_internals", issue = "44838")]
103 pub struct Wrapper<T>(pub T);
104
105 /// Tells which elements can be copied and displayed
106 #[unstable(feature = "generic_assert_internals", issue = "44838")]
107 pub trait Printable: Copy + Debug {}
108
109 impl<T> Printable for T where T: Copy + Debug {}