1#![allow(missing_docs)]
3
4use std::{
5 fmt::{self, Debug, Write as FmtWrite},
6 io,
7 marker::PhantomData,
8};
9
10use super::{
11 c_functions::*,
12 iterator::{DoubleEndedIteratorFns, IteratorFns, MakeDoubleEndedIteratorFns, MakeIteratorFns},
13 traits::{GetSerializeProxyType, IteratorItemOrDefault, SerializeType},
14 type_info::TypeInfoFor,
15 *,
16};
17
18use crate::{
19 marker_type::{ErasedObject, NonOwningPhantom},
20 pointer_trait::GetPointerKind,
21 prefix_type::{panic_on_missing_fieldname, WithMetadata},
22 sabi_types::{RMut, RRef, StaticRef},
23 std_types::{RIoError, RNone, RSeekFrom, RSome},
24 type_level::{
25 downcasting::GetUTID,
26 impl_enum::{Implemented, Unimplemented},
27 trait_marker,
28 },
29 utils::Transmuter,
30 InterfaceType, StableAbi,
31};
32
33pub trait MakeVTable<'borr, T, OrigPtr, CanDowncast> {
38 type Helper0;
39
40 const HELPER0: Self::Helper0;
41
42 type Helper1;
43
44 const HELPER1: Self::Helper1;
45
46 const VTABLE_REF: Self;
47}
48
49macro_rules! declare_meta_vtable {
50 (
51 interface=$interf:ident;
52 value=$value:ident;
53 erased_pointer=$erased_ptr:ident;
54 original_pointer=$orig_ptr:ident;
55 can_downcast=$can_downcast:ident;
56
57 auto_traits[
58 $([
59 impl $auto_trait:ident ($auto_trait_path:path)
60 where [ $($phantom_where_clause:tt)* ]
61 query_fn = $auto_trait_query:ident;
62 ])*
63 ]
64
65 marker_traits[
66 $([
67 impl $marker_trait:ident($marker_trait_path:path)
68 where [ $($marker_where_clause:tt)* ]
69 query_fn = $marker_trait_query:ident;
70 ])*
71 ]
72
73 $([
74 $( #[$field_attr:meta] )*
75 $field:ident : $field_ty:ty ;
76 priv $priv_field:ident;
77 option=$option_ty:ident,$some_constr:ident,$none_constr:ident;
78 field_index=$field_index:ident;
79 query_fn = $trait_query:ident;
80
81 $(struct_bound=$struct_bound:expr;)*
82
83 impl[$($impl_params:tt)*] VtableFieldValue<$selector:ident($trait_path:path)>
84 where [ $($where_clause:tt)* ]
85 { $field_value:expr }
86 ])*
87 ) => (
88
89 #[repr(C,align(16))]
92 #[derive(StableAbi)]
93 #[sabi(
94 with_field_indices,
96 kind(Prefix(prefix_ref_docs = "\
97 A pointer to the vtable of [`DynTrait`].\
98 \n\n\
99 This is only exposed to allow users to construct\
100 [`DynTrait`]s with a generic `I` type parameter.\
101 ")),
102 missing_field(panic),
103 prefix_bound(I: InterfaceType),
104 bound(I: IteratorItemOrDefault<'borr>),
105 bound(<I as IteratorItemOrDefault<'borr>>::Item: StableAbi),
106 bound(I: GetSerializeProxyType<'borr>),
107 bound(<I as GetSerializeProxyType<'borr>>::ProxyType: StableAbi),
108 $($(bound=$struct_bound,)*)*
109 )]
110 pub struct VTable<'borr,$erased_ptr,$interf>{
111 pub type_info:&'static TypeInfo,
112 _marker:NonOwningPhantom<($erased_ptr,$interf,&'borr())>,
113 pub drop_ptr:unsafe extern "C" fn(RMut<'_, $erased_ptr>),
114 $(
115 $( #[$field_attr] )*
116 $priv_field:$option_ty<$field_ty>,
117 )*
118 }
119
120
121 impl<'borr,$erased_ptr,$interf> VTable_Ref<'borr,$erased_ptr,$interf>{
122 $(
123 pub fn $field(&self)->$field_ty
124 where
125 $interf:InterfaceType<$selector=Implemented<trait_marker::$selector>>,
126 {
127 match self.$priv_field().into() {
128 Some(v)=>v,
129 None=>panic_on_missing_fieldname::<
130 VTable<'borr,$erased_ptr,$interf>,
131 >(
132 Self::$field_index,
133 self._prefix_type_layout(),
134 )
135 }
136 }
137 )*
138 pub fn iter(
139 &self
140 )->IteratorFns< <I as IteratorItemOrDefault<'borr>>::Item >
141 where
142 $interf:InterfaceType<Iterator=Implemented<trait_marker::Iterator>>,
143 $interf:IteratorItemOrDefault<'borr>,
144 {
145 unsafe{
146 std::mem::transmute::<
147 IteratorFns< () >,
148 IteratorFns< <I as IteratorItemOrDefault<'borr>>::Item >
149 >( self.erased_iter() )
150 }
151 }
152
153 pub fn back_iter(
154 &self
155 )->DoubleEndedIteratorFns< <I as IteratorItemOrDefault<'borr>>::Item >
156 where
157 $interf:InterfaceType<
158 DoubleEndedIterator=Implemented<trait_marker::DoubleEndedIterator>
159 >,
160 $interf:IteratorItemOrDefault<'borr>,
161 {
162 unsafe{
163 std::mem::transmute::<
164 DoubleEndedIteratorFns< () >,
165 DoubleEndedIteratorFns< <I as IteratorItemOrDefault<'borr>>::Item >
166 >( self.erased_back_iter() )
167 }
168 }
169
170 pub fn serialize<'s>(&self)->UnerasedSerializeFn<'s,I>
171 where
172 I:InterfaceType<Serialize=Implemented<trait_marker::Serialize>>,
173 I:GetSerializeProxyType<'s>,
174 {
175 unsafe{
176 std::mem::transmute::<
177 unsafe extern "C" fn(RRef<'_, ErasedObject>)->RResult<ErasedObject,RBoxError>,
178 UnerasedSerializeFn<'s,I>,
179 >( self.erased_serialize() )
180 }
181 }
182 }
183
184
185 pub type UnerasedSerializeFn<'s,I>=
186 unsafe extern "C" fn(
187 RRef<'s, ErasedObject>
188 )->RResult<<I as GetSerializeProxyType<'s>>::ProxyType,RBoxError>;
189
190
191 pub type VTableFieldType<'borr,Selector,$value,$erased_ptr,$orig_ptr,$interf>=
193 <Selector as VTableFieldType_<'borr,$value,$erased_ptr,$orig_ptr,$interf>>::Field;
194
195 pub trait VTableFieldType_<'borr,$value,$erased_ptr,$orig_ptr,$interf>{
197 type Field;
198 }
199
200 pub trait VTableFieldValue<'borr,Ty,$value,$erased_ptr,$orig_ptr,$interf>{
203 const FIELD:Ty;
204 }
205
206 pub trait MarkerTrait<'borr,$value,$erased_ptr,$orig_ptr>{}
207
208
209 $(
210 impl<'borr,$value,$erased_ptr,$orig_ptr,$interf>
211 VTableFieldType_<'borr,$value,$erased_ptr,$orig_ptr,$interf>
212 for trait_marker::$selector
213 where
214 $interf:InterfaceType,
215 {
216 type Field=$field_ty;
217 }
218
219
220 impl<'borr,AnyFieldTy,$value,$erased_ptr,$orig_ptr,$interf>
221 VTableFieldValue<
222 'borr,
223 $option_ty<AnyFieldTy>,
224 $value,
225 $erased_ptr,
226 $orig_ptr,
227 $interf
228 >
229 for Unimplemented<trait_marker::$selector>
230 {
231 const FIELD:$option_ty<AnyFieldTy>=$none_constr;
232 }
233
234 impl<'borr,$value,$erased_ptr,$orig_ptr,$interf,$($impl_params)*>
235 VTableFieldValue<
236 'borr,
237 $option_ty<$field_ty>,
238 $value,
239 $erased_ptr,
240 $orig_ptr,
241 $interf
242 >
243 for Implemented<trait_marker::$selector>
244 where
245 $interf:InterfaceType,
246 $($where_clause)*
247 {
248 const FIELD:$option_ty<$field_ty>=
249 $some_constr($field_value);
250 }
251 )*
252
253
254
255 impl<'borr,Anything,$value,$erased_ptr,$orig_ptr>
256 MarkerTrait<'borr,$value,$erased_ptr,$orig_ptr>
257 for Unimplemented<Anything>
258 {}
259
260 $(
261 impl<'borr,$value,$erased_ptr,$orig_ptr>
262 MarkerTrait<'borr,$value,$erased_ptr,$orig_ptr>
263 for Implemented<trait_marker::$auto_trait>
264 where $($phantom_where_clause)*
265 {}
266 )*
267
268 $(
269 impl<'borr,$value,$erased_ptr,$orig_ptr>
270 MarkerTrait<'borr,$value,$erased_ptr,$orig_ptr>
271 for Implemented<trait_marker::$marker_trait>
272 where $($marker_where_clause)*
273 {}
274 )*
275
276 impl<'borr,$value,$erased_ptr,$orig_ptr,$interf,$can_downcast>
279 MakeVTable<'borr,$value,$orig_ptr,$can_downcast>
280 for VTable_Ref<'borr,$erased_ptr,$interf>
281 where
282 $interf:InterfaceType,
283 $can_downcast: GetUTID<$value>,
284 $(
285 $interf::$auto_trait:
286 MarkerTrait<'borr,$value,$erased_ptr,$orig_ptr>,
287 )*
288 $(
289 $interf::$marker_trait:
290 MarkerTrait<'borr,$value,$erased_ptr,$orig_ptr>,
291 )*
292 $(
293 $interf::$selector: VTableFieldValue<
294 'borr,
295 $option_ty<$field_ty>,
296 $value,
297 $erased_ptr,
298 $orig_ptr,
299 $interf,
300 >,
301 )*
302 {
303 #[doc(hidden)]
304 type Helper0 = WithMetadata<VTable<'borr,$erased_ptr,$interf>>;
305
306 #[doc(hidden)]
307 const HELPER0: Self::Helper0 = WithMetadata::new(VTable{
308 type_info: <TypeInfoFor<$value, $interf, $can_downcast>>::INFO,
309 drop_ptr:drop_pointer_impl::<$orig_ptr,$erased_ptr>,
310 $(
311 $priv_field:
312 <$interf::$selector as
313 VTableFieldValue<
314 $option_ty<VTableFieldType<
315 'borr,
316 trait_marker::$selector,
317 $value,
318 $erased_ptr,
319 $orig_ptr,
320 $interf,
321 >>,
322 $value,
323 $erased_ptr,
324 $orig_ptr,
325 $interf,
326 >
327 >::FIELD,
328 )*
329 _marker:NonOwningPhantom::NEW,
330 });
331
332 #[doc(hidden)]
333 type Helper1 = StaticRef<WithMetadata<VTable<'borr,ErasedPtr,I>>>;
334
335 #[doc(hidden)]
336 const HELPER1: Self::Helper1 = unsafe {
337 StaticRef::from_raw(
339 &<Self as MakeVTable<'borr,$value,$orig_ptr,$can_downcast>>::HELPER0
340 )
341 };
342
343 const VTABLE_REF: Self = Self(
344 <Self as MakeVTable<'borr,$value,$orig_ptr,$can_downcast>>::HELPER1.as_prefix()
345 );
346
347 }
348
349 #[allow(non_upper_case_globals)]
351 pub trait MakeRequiredTraits: InterfaceType {
352 #[doc(hidden)]
353 const __MakeRequiredTraits_BLANKET_IMPL: PrivStruct<Self>;
355
356 const MAKE: RequiredTraits = RequiredTraits::new::<Self>();
358 }
359
360 #[allow(non_upper_case_globals)]
361 impl<I> MakeRequiredTraits for I
362 where
363 I:InterfaceType,
364 {
365 const __MakeRequiredTraits_BLANKET_IMPL:PrivStruct<Self>=
366 PrivStruct(PhantomData);
367 }
368
369
370 impl<'borr,$erased_ptr,$interf> Debug for VTable_Ref<'borr,$erased_ptr,$interf>
371 where
372 $interf:InterfaceType,
373 {
374 fn fmt(&self,f:&mut fmt::Formatter<'_>)->fmt::Result {
375 f.debug_struct("VTable_Ref")
376 .field("type_info",&self.type_info())
377 .finish()
378 }
379 }
380
381 declare_enabled_traits!{
382 auto_traits[
383 $(($auto_trait, $auto_trait_query, $auto_trait_path),)*
384 ]
385
386 regular_traits[
387 $(($marker_trait, $marker_trait_query, $marker_trait_path),)*
388 $(($selector, $trait_query, $trait_path),)*
389 (Deserialize, contains_deserialize, serde::Deserialize),
390 ]
391 }
392 )
393}
394
395declare_meta_vtable! {
396 interface=I;
397 value =T;
398 erased_pointer=ErasedPtr;
399 original_pointer=OrigP;
400 can_downcast = CanDowncast;
401
402 auto_traits[
403 [
404 impl Send(std::marker::Send) where [OrigP:Send, T:Send]
405 query_fn = contains_send;
406 ]
407 [
408 impl Sync(std::marker::Sync) where [OrigP:Sync, T:Sync]
409 query_fn = contains_sync;
410 ]
411 [
412 impl Unpin(std::marker::Unpin) where [T: Unpin]
413 query_fn = contains_unpin;
414 ]
415 ]
416
417 marker_traits[
418 [
419 impl Error(std::error::Error) where [T:std::error::Error]
420 query_fn = contains_error;
421 ]
422 ]
423
424 [
425 #[sabi(accessible_if= <I as MakeRequiredTraits>::MAKE.contains_clone())]
426 clone_ptr: unsafe extern "C" fn(RRef<'_, ErasedPtr>)->ErasedPtr;
427 priv _clone_ptr;
428 option=Option,Some,None;
429 field_index=field_index_for__clone_ptr;
430 query_fn = contains_clone;
431
432 impl[] VtableFieldValue<Clone(std::clone::Clone)>
433 where [OrigP:Clone]
434 {
435 clone_pointer_impl::<OrigP,ErasedPtr>
436 }
437 ]
438 [
439 #[sabi(accessible_if= <I as MakeRequiredTraits>::MAKE.contains_default())]
440 default_ptr: unsafe extern "C" fn()->ErasedPtr ;
441 priv _default_ptr;
442 option=Option,Some,None;
443 field_index=field_index_for__default_ptr;
444 query_fn = contains_default;
445
446 impl[] VtableFieldValue<Default(std::default::Default)>
447 where [
448 OrigP:GetPointerKind,
449 OrigP:DefaultImpl<<OrigP as GetPointerKind>::Kind>,
450 ]{
451 default_pointer_impl::<OrigP,ErasedPtr>
452 }
453 ]
454 [
455 #[sabi(accessible_if= <I as MakeRequiredTraits>::MAKE.contains_display())]
456 display:unsafe extern "C" fn(RRef<'_, ErasedObject>,FormattingMode,&mut RString)->RResult<(),()>;
457 priv _display;
458 option=Option,Some,None;
459 field_index=field_index_for__display;
460 query_fn = contains_display;
461
462 impl[] VtableFieldValue<Display(std::fmt::Display)>
463 where [T:Display]
464 {
465 display_impl::<T>
466 }
467 ]
468 [
469 #[sabi(accessible_if= <I as MakeRequiredTraits>::MAKE.contains_debug())]
470 debug:unsafe extern "C" fn(RRef<'_, ErasedObject>,FormattingMode,&mut RString)->RResult<(),()>;
471 priv _debug;
472 option=Option,Some,None;
473 field_index=field_index_for__debug;
474 query_fn = contains_debug;
475
476 impl[] VtableFieldValue<Debug(std::fmt::Debug)>
477 where [T:Debug]
478 {
479 debug_impl::<T>
480 }
481 ]
482 [
483 #[sabi(unsafe_change_type=
484 for<'s>
485 unsafe extern "C" fn(
486 RRef<'s, ErasedObject>
487 )->RResult<<I as GetSerializeProxyType<'s>>::ProxyType,RBoxError>
488 )]
489 #[sabi(accessible_if= <I as MakeRequiredTraits>::MAKE.contains_serialize())]
490 erased_serialize:unsafe extern "C" fn(RRef<'_, ErasedObject>)->RResult<ErasedObject,RBoxError>;
491 priv priv_serialize;
492 option=Option,Some,None;
493 field_index=field_index_for_priv_serialize;
494 query_fn = contains_serialize;
495
496 impl[] VtableFieldValue<Serialize(serde::Serialize)>
497 where [
498 T:for<'s>SerializeType<'s,Interface=I>,
499 I:for<'s>SerializeProxyType<'s>,
500 ]{
501 unsafe{
502 Transmuter::<
503 unsafe extern "C" fn(
504 RRef<'_, ErasedObject>
505 )->RResult<<I as SerializeProxyType<'_>>::Proxy,RBoxError>,
506 unsafe extern "C" fn(RRef<'_, ErasedObject>)->RResult<ErasedObject,RBoxError>
507 >{
508 from:serialize_impl::<T,I>
509 }.to
510 }
511 }
512 ]
513 [
514 #[sabi(accessible_if= <I as MakeRequiredTraits>::MAKE.contains_partial_eq())]
515 partial_eq: unsafe extern "C" fn(RRef<'_, ErasedObject>,RRef<'_, ErasedObject>)->bool;
516 priv _partial_eq;
517 option=Option,Some,None;
518 field_index=field_index_for__partial_eq;
519 query_fn = contains_partial_eq;
520
521 impl[] VtableFieldValue<PartialEq(std::cmp::PartialEq)>
522 where [T:PartialEq,]
523 {
524 partial_eq_impl::<T>
525 }
526 ]
527 [
528 #[sabi(accessible_if= <I as MakeRequiredTraits>::MAKE.contains_cmp())]
529 cmp: unsafe extern "C" fn(RRef<'_, ErasedObject>,RRef<'_, ErasedObject>)->RCmpOrdering;
530 priv _cmp;
531 option=Option,Some,None;
532 field_index=field_index_for__cmp;
533 query_fn = contains_cmp;
534
535 impl[] VtableFieldValue<Ord(std::cmp::Ord)>
536 where [T:Ord,]
537 {
538 cmp_ord::<T>
539 }
540 ]
541 [
542 #[sabi(accessible_if= <I as MakeRequiredTraits>::MAKE.contains_partial_cmp())]
543 partial_cmp:unsafe extern "C" fn(RRef<'_, ErasedObject>,RRef<'_, ErasedObject>)->ROption<RCmpOrdering>;
544 priv _partial_cmp;
545 option=Option,Some,None;
546 field_index=field_index_for__partial_cmp;
547 query_fn = contains_partial_cmp;
548
549 impl[] VtableFieldValue<PartialOrd(std::cmp::PartialOrd)>
550 where [T:PartialOrd,]
551 {
552 partial_cmp_ord::<T>
553 }
554 ]
555 [
556 #[sabi(accessible_if= <I as MakeRequiredTraits>::MAKE.contains_hash())]
557 hash:unsafe extern "C" fn(RRef<'_, ErasedObject>,trait_objects::HasherObject<'_>);
558 priv _hash;
559 option=Option,Some,None;
560 field_index=field_index_for__hash;
561 query_fn = contains_hash;
562
563 impl[] VtableFieldValue<Hash(std::hash::Hash)>
564 where [T:Hash]
565 {
566 hash_Hash::<T>
567 }
568 ]
569 [
570 #[sabi(
571 unsafe_change_type=
572 ROption<IteratorFns< <I as IteratorItemOrDefault<'borr>>::Item >>
573 )]
574 #[sabi(accessible_if= <I as MakeRequiredTraits>::MAKE.contains_iterator())]
575 erased_iter:IteratorFns< () >;
576 priv _iter;
577 option=ROption,RSome,RNone;
578 field_index=field_index_for__iter;
579 query_fn = contains_iterator;
580
581 impl[] VtableFieldValue<Iterator(std::iter::Iterator)>
582 where [
583 T:Iterator,
584 I:IteratorItemOrDefault<'borr,Item=<T as Iterator>::Item>,
585 ]{
586 MakeIteratorFns::<T>::NEW
587 }
588 ]
589 [
590 #[sabi(
591 unsafe_change_type=
592 ROption<DoubleEndedIteratorFns< <I as IteratorItemOrDefault<'borr>>::Item >>
593 )]
594 #[sabi(accessible_if= <I as MakeRequiredTraits>::MAKE.contains_double_ended_iterator())]
595 erased_back_iter:DoubleEndedIteratorFns< () >;
596 priv _back_iter;
597 option=ROption,RSome,RNone;
598 field_index=field_index_for__back_iter;
599 query_fn = contains_double_ended_iterator;
600
601 impl[] VtableFieldValue<DoubleEndedIterator(std::iter::DoubleEndedIterator)>
602 where [
603 T:DoubleEndedIterator,
604 I:IteratorItemOrDefault<'borr,Item=<T as Iterator>::Item>,
605 ]{
606 MakeDoubleEndedIteratorFns::<T>::NEW
607 }
608 ]
609 [
610 #[sabi(accessible_if= <I as MakeRequiredTraits>::MAKE.contains_fmt_write())]
611 fmt_write_str:unsafe extern "C" fn(RMut<'_, ErasedObject>,RStr<'_>)->RResult<(),()>;
612 priv _fmt_write_str;
613 option=Option,Some,None;
614 field_index=field_index_for__fmt_write_str;
615 query_fn = contains_fmt_write;
616
617 impl[] VtableFieldValue<FmtWrite(std::fmt::Write)>
618 where [ T:FmtWrite ]
619 {
620 write_str_fmt_write::<T>
621 }
622 ]
623 [
624 #[sabi(accessible_if= <I as MakeRequiredTraits>::MAKE.contains_io_write())]
625 io_write:IoWriteFns;
626 priv _io_write;
627 option=ROption,RSome,RNone;
628 field_index=field_index_for__io_write;
629 query_fn = contains_io_write;
630
631 impl[] VtableFieldValue<IoWrite(std::io::Write)>
632 where [ T:io::Write ]
633 {
634 MakeIoWriteFns::<T>::NEW
635 }
636 ]
637 [
638 #[sabi(accessible_if= <I as MakeRequiredTraits>::MAKE.contains_io_read())]
639 io_read:IoReadFns;
640 priv _io_read;
641 option=ROption,RSome,RNone;
642 field_index=field_index_for__io_read;
643 query_fn = contains_io_read;
644
645 impl[] VtableFieldValue<IoRead(std::io::Read)>
646 where [ T:io::Read ]
647 {
648 MakeIoReadFns::<T>::NEW
649 }
650 ]
651 [
652 #[sabi(accessible_if= <I as MakeRequiredTraits>::MAKE.contains_io_bufread())]
653 io_bufread:IoBufReadFns;
654 priv _io_bufread;
655 option=ROption,RSome,RNone;
656 field_index=field_index_for__io_bufread;
657 query_fn = contains_io_bufread;
658
659 impl[] VtableFieldValue<IoBufRead(std::io::BufRead)>
660 where [
661 T:io::BufRead,
662 I:InterfaceType<IoRead= Implemented<trait_marker::IoRead>>
663 ]{
664 MakeIoBufReadFns::<T>::NEW
665 }
666 ]
667 [
668 #[sabi(last_prefix_field)]
669 #[sabi(accessible_if= <I as MakeRequiredTraits>::MAKE.contains_io_seek())]
670 io_seek:unsafe extern "C" fn(RMut<'_, ErasedObject>,RSeekFrom)->RResult<u64,RIoError>;
671 priv _io_seek;
672 option=Option,Some,None;
673 field_index=field_index_for__io_seek;
674 query_fn = contains_io_seek;
675
676 impl[] VtableFieldValue<IoSeek(std::io::Seek)>
677 where [ T:io::Seek ]
678 {
679 io_Seek_seek::<T>
680 }
681 ]
682}
683
684#[doc(hidden)]
689pub struct PrivStruct<T>(PhantomData<T>);