]> git.proxmox.com Git - rustc.git/blob - library/core/src/asserting.rs
New upstream version 1.63.0+dfsg1
[rustc.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 {}