abi_stable/erased_types/
enabled_traits_macro.rs1macro_rules! declare_enabled_traits {
2 (
3 auto_traits[
4 $(($auto_trait:ident, $auto_trait_query:ident, $auto_trait_path:path)),* $(,)*
5 ]
6
7 regular_traits[
8 $(($regular_trait:ident, $regular_trait_query:ident, $regular_trait_path:path)),* $(,)*
9 ]
10 ) => (
11 use crate::{
12 abi_stability::extra_checks::{
13 TypeCheckerMut,ExtraChecks,
14 ForExtraChecksImplementor,ExtraChecksError,
15 },
16 type_layout::TypeLayout,
17 std_types::{RCowSlice,RResult},
18 };
19
20 use core_extensions::strings::StringExt;
21
22 #[allow(non_upper_case_globals)]
23 mod auto_trait_mask{
24 #[repr(u32)]
25 enum __Index {
26 $($auto_trait,)*
27 }
28 $(pub(super) const $auto_trait: u16 = 1u16 << __Index::$auto_trait as u32;)*
29 }
30
31 #[allow(non_upper_case_globals)]
32 mod regular_trait_mask{
33 #[repr(u32)]
34 enum __Index {
35 $($regular_trait,)*
36 }
37 $(pub(super) const $regular_trait: u64 = 1u64 << __Index::$regular_trait as u32;)*
38 }
39
40
41 #[repr(C)]
54 #[derive(Copy,Clone,StableAbi)]
55 pub struct RequiredTraits{
56 auto_traits:u16,
57 regular_traits:u64,
58 }
59
60 impl RequiredTraits {
61 pub const fn new<I: InterfaceType>() -> Self {
63 use crate::type_level::impl_enum::Implementability;
64
65 RequiredTraits {
66 auto_traits: $(
67 if <I::$auto_trait as Implementability>::IS_IMPLD {
68 auto_trait_mask::$auto_trait
69 } else {
70 0
71 }
72 )|*,
73 regular_traits: $(
74 if <I::$regular_trait as Implementability>::IS_IMPLD {
75 regular_trait_mask::$regular_trait
76 } else {
77 0
78 }
79 )|*
80 }
81 }
82
83 $(
84 #[doc = concat!(
85 "Whether the [`",
86 stringify!($auto_trait_path),
87 "`] trait is required",
88 )]
89 pub const fn $auto_trait_query(self) -> bool {
90 (self.auto_traits & auto_trait_mask::$auto_trait) != 0
91 }
92 )*
93 $(
94 #[doc = concat!(
95 "Whether the [`",
96 stringify!($regular_trait_path),
97 "`] trait is required",
98 )]
99 pub const fn $regular_trait_query(self) -> bool {
100 (self.regular_traits & regular_trait_mask::$regular_trait) != 0
101 }
102 )*
103 }
104
105 impl Debug for RequiredTraits{
106 fn fmt(&self,f:&mut fmt::Formatter<'_>)->fmt::Result{
107 use self::debug_impl_details::{EnabledAutoTraits,EnabledRegularTraits};
108
109 f.debug_struct("RequiredTraits")
110 .field("auto_traits_bits",&self.auto_traits)
111 .field("auto_traits",&EnabledAutoTraits{traits:self.auto_traits})
112 .field("regular_traits_bits",&self.regular_traits)
113 .field("regular_traits",&EnabledRegularTraits{traits:self.regular_traits})
114 .finish()
115 }
116 }
117
118 impl Display for RequiredTraits{
119 fn fmt(&self,f:&mut fmt::Formatter<'_>)->fmt::Result{
120 f.write_str("RequiredTraits\n")?;
121
122 f.write_str("Auto traits:")?;
123 if self.auto_traits==0 {
124 f.write_str("<no_traits>")?;
125 }else{
126 $(
127 if (self.auto_traits&auto_trait_mask::$auto_trait)!=0 {
128 f.write_str(concat!(" ",stringify!($auto_trait)))?;
129 }
130 )*
131 }
132 writeln!(f,)?;
133
134 f.write_str("Impld traits:")?;
135 if self.regular_traits==0 {
136 f.write_str("<no_traits>")?;
137 }else{
138 $(
139 if (self.regular_traits®ular_trait_mask::$regular_trait)!=0 {
140 f.write_str(concat!(" ",stringify!($regular_trait)))?;
141 }
142 )*
143 }
144 writeln!(f,)?;
145
146 Ok(())
147 }
148 }
149
150
151 unsafe impl ExtraChecks for RequiredTraits {
152 fn type_layout(&self)->&'static TypeLayout{
153 <Self as StableAbi>::LAYOUT
154 }
155
156 fn check_compatibility(
157 &self,
158 _layout_containing_self:&'static TypeLayout,
159 layout_containing_other:&'static TypeLayout,
160 checker:TypeCheckerMut<'_>,
161 )->RResult<(), ExtraChecksError> {
162 Self::downcast_with_layout(layout_containing_other,checker,|other,_|{
163 if self.auto_traits!=other.auto_traits {
164 Err(ImpldTraitsError{
165 kind:ImpldTraitsErrorKind::MismatchedAutoTraits,
166 expected:self.clone(),
167 found:other.clone(),
168 })
169 }else if (self.regular_traits&other.regular_traits)!=self.regular_traits {
170 Err(ImpldTraitsError{
171 kind:ImpldTraitsErrorKind::UnimpldTraits,
172 expected:self.clone(),
173 found:other.clone(),
174 })
175 }else{
176 Ok(())
177 }
178 })
179 }
180
181 fn nested_type_layouts(&self)->RCowSlice<'_, &'static TypeLayout>{
182 RCowSlice::from_slice(&[])
183 }
184 }
185
186 mod debug_impl_details{
187 use super::*;
188
189 pub(super) struct EnabledAutoTraits{
190 pub(super) traits:u16,
191 }
192
193 impl Debug for EnabledAutoTraits{
194 fn fmt(&self,f:&mut fmt::Formatter<'_>)->fmt::Result{
195 let mut ds=f.debug_set();
196 $(
197 if (self.traits&auto_trait_mask::$auto_trait)!=0 {
198 ds.entry(&stringify!( $auto_trait ));
199 }
200 )*
201 ds.finish()
202 }
203 }
204
205
206 pub(super) struct EnabledRegularTraits{
207 pub(super) traits:u64,
208 }
209
210 impl Debug for EnabledRegularTraits{
211 fn fmt(&self,f:&mut fmt::Formatter<'_>)->fmt::Result{
212 let mut ds=f.debug_set();
213 $(
214 if (self.traits®ular_trait_mask::$regular_trait)!=0 {
215 ds.entry(&stringify!( $regular_trait ));
216 }
217 )*
218 ds.finish()
219 }
220 }
221 }
222
223
224 #[derive(Debug,Clone)]
228 pub struct ImpldTraitsError{
229 kind:ImpldTraitsErrorKind,
230 expected:RequiredTraits,
231 found:RequiredTraits,
232 }
233
234 #[derive(Debug,Clone)]
235 pub enum ImpldTraitsErrorKind{
236 MismatchedAutoTraits,
237 UnimpldTraits,
238 }
239
240 impl Display for ImpldTraitsError{
241 fn fmt(&self,f:&mut fmt::Formatter<'_>)->fmt::Result{
242
243 let msg=match self.kind {
244 ImpldTraitsErrorKind::MismatchedAutoTraits=>
245 "Expected auto traits to be exactly the same",
246 ImpldTraitsErrorKind::UnimpldTraits=>
247 "`Expected` does not contain a subset of the traits in`Found`",
248 };
249 f.write_str(msg)?;
250 writeln!(f,)?;
251
252 writeln!(f,"Expected:\n{}",self.expected.to_string().left_padder(4))?;
253 writeln!(f,"Found:\n{}",self.found.to_string().left_padder(4))?;
254
255 Ok(())
256 }
257 }
258
259 impl std::error::Error for ImpldTraitsError{}
260
261 )
262}