abi_stable/erased_types/
vtable.rs

1//! Contains `DynTrait<_>`'s vtable,and related types/traits.
2#![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
33/// Csontructs a vtable.
34///
35/// This is only exposed to allow users to construct
36/// [`DynTrait`]s with a generic `I` type parameter.
37pub 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        /// This is the vtable for DynTrait<_>,
90        ///
91        #[repr(C,align(16))]
92        #[derive(StableAbi)]
93        #[sabi(
94            // debug_print,
95            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        /// Returns the type of a vtable field.
192        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        /// Returns the type of a vtable field.
196        pub trait VTableFieldType_<'borr,$value,$erased_ptr,$orig_ptr,$interf>{
197            type Field;
198        }
199
200        /// Returns the value of a vtable field in the current binary
201        /// (this can be a different value in a dynamically_linked_library/executable).
202        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        ///////////////////////////////////////////////////////////
277
278        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                // relying on static promotion, this will compile-error otherwise
338                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        /// For constructing a [`RequiredTraits`] constant.
350        #[allow(non_upper_case_globals)]
351        pub trait MakeRequiredTraits: InterfaceType {
352            #[doc(hidden)]
353            // Used to prevent users from implementing this trait.
354            const __MakeRequiredTraits_BLANKET_IMPL: PrivStruct<Self>;
355
356            /// Describes which traits are required by `Self: `[`InterfaceType`],
357            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//////////////
685
686/// Used to prevent MakeRequiredTraits being implemented outside this module,
687/// since it is only constructed in the impl of MakeRequiredTraits in this module.
688#[doc(hidden)]
689pub struct PrivStruct<T>(PhantomData<T>);