abi_stable/abi_stability/
stable_abi_trait.rs

1//! Where the StableAbi trait is declared,as well as related types/traits.
2
3use core_extensions::type_level_bool::{Boolean, False, True};
4use std::{
5    cell::{Cell, UnsafeCell},
6    marker::{PhantomData, PhantomPinned},
7    mem::ManuallyDrop,
8    num::{NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, Wrapping},
9    pin::Pin,
10    ptr::NonNull,
11    sync::atomic::{AtomicBool, AtomicIsize, AtomicPtr, AtomicUsize},
12};
13
14use crate::{
15    abi_stability::get_static_equivalent::GetStaticEquivalent_,
16    reflection::ModReflMode,
17    sabi_types::Constructor,
18    std_types::{utypeid::UTypeId, RSlice},
19    type_layout::{
20        CompTLField, CompTLFields, DiscriminantRepr, GenericTLData, GenericTLEnum, ItemInfo,
21        LifetimeRange, MonoTLData, MonoTLEnum, MonoTypeLayout, ReprAttr, StartLen, TLDiscriminants,
22        TLPrimitive, TypeLayout,
23    },
24};
25
26///////////////////////
27
28/// Represents a type whose layout is stable.
29///
30/// This trait can be derived using
31/// [`#[derive(StableAbi)]`](derive@crate::StableAbi).
32///
33/// # Safety
34///
35/// The layout specified in `LAYOUT` must be correct,
36/// otherwise type checking when loading a dynamic library would be unsound,
37/// and passing this into a dynamic library would be equivalent to transmuting it.
38///
39/// # Caveats
40///
41/// This trait cannot be directly implemented for functions that take lifetime parameters,
42/// because of that, [`#[derive(StableAbi)]`](derive@crate::StableAbi)
43/// detects the presence of `extern fn` types in type definitions.
44pub unsafe trait StableAbi: GetStaticEquivalent_ {
45    /// Whether this type has a single invalid bit-pattern.
46    ///
47    /// Possible values: [`True`]/[`False`]
48    ///
49    /// Some standard library types have a single value that is invalid for them eg:0,null.
50    /// these types are the only ones which can be stored in a `Option<_>` that implements StableAbi.
51    ///
52    /// For an alternative to `Option<T>` for types where
53    /// `IsNonZeroType = False`, you can use [`ROption`].
54    ///
55    /// Non-exhaustive list of std types that are NonZero:
56    ///
57    /// - `&T` (any T).
58    ///
59    /// - `&mut T` (any T).
60    ///
61    /// - `extern "C" fn()`.
62    ///
63    /// - `std::ptr::NonNull`
64    ///
65    /// - `std::num::NonZero*`
66    ///
67    /// [`True`]: crate::reexports::True
68    /// [`False`]: crate::reexports::False
69    /// [`ROption`]: crate::std_types::ROption
70    type IsNonZeroType: Boolean;
71
72    /// The layout of the type provided by implementors.
73    const LAYOUT: &'static TypeLayout;
74
75    /// `const`-equivalents of the associated types.
76    const ABI_CONSTS: AbiConsts = AbiConsts {
77        type_id: Constructor(crate::std_types::utypeid::new_utypeid::<Self::StaticEquivalent>),
78        is_nonzero: <Self::IsNonZeroType as Boolean>::VALUE,
79    };
80}
81
82/// A type that only has a stable layout when a `PrefixRef` to it is used.
83///
84/// Types that implement this trait usually have a `_Prefix` suffix.
85///
86/// # Safety
87///
88/// This trait can only be implemented by the `StableAbi` derive
89/// on types that also use the `#[sabi(kind(Prefix))]` attribute,
90/// implementing the trait for a macro generated type.
91pub unsafe trait PrefixStableAbi: GetStaticEquivalent_ {
92    /// Whether this type has a single invalid bit-pattern.
93    type IsNonZeroType: Boolean;
94
95    /// The layout of the type, provided by implementors.
96    const LAYOUT: &'static TypeLayout;
97
98    /// `const`-equivalents of the associated types.
99    const ABI_CONSTS: AbiConsts = AbiConsts {
100        type_id: Constructor(crate::std_types::utypeid::new_utypeid::<Self::StaticEquivalent>),
101        is_nonzero: <Self::IsNonZeroType as Boolean>::VALUE,
102    };
103}
104
105///////////////////////
106
107/// Contains constants equivalent to the associated types in StableAbi.
108#[derive(Debug, Copy, Clone, PartialEq, Eq)]
109#[repr(C)]
110#[derive(StableAbi)]
111pub struct AbiConsts {
112    /// A function to get the unique identifier for some type
113    pub type_id: Constructor<UTypeId>,
114
115    /// Whether the type uses non-zero value optimization,
116    /// if true then an `Option<Self>` implements StableAbi.
117    pub is_nonzero: bool,
118}
119
120impl AbiConsts {
121    /// Gets the `UTypeId` returned by the `type_id` field.
122    #[inline]
123    pub fn get_type_id(&self) -> UTypeId {
124        self.type_id.get()
125    }
126}
127
128///////////////////////////////////////////////////////////////////////////////
129
130/// Retrieves the TypeLayout of `T: StableAbi`,
131pub extern "C" fn get_type_layout<T>() -> &'static TypeLayout
132where
133    T: StableAbi,
134{
135    T::LAYOUT
136}
137
138/// Retrieves the TypeLayout of `T: PrefixStableAbi`,
139pub extern "C" fn get_prefix_field_type_layout<T>() -> &'static TypeLayout
140where
141    T: PrefixStableAbi,
142{
143    <T as PrefixStableAbi>::LAYOUT
144}
145
146#[doc(hidden)]
147pub extern "C" fn __sabi_opaque_field_type_layout<T>() -> &'static TypeLayout
148where
149    T: StableAbi,
150{
151    <UnsafeOpaqueField<T> as StableAbi>::LAYOUT
152}
153#[doc(hidden)]
154pub extern "C" fn __opaque_field_type_layout<T>() -> &'static TypeLayout {
155    <UnsafeOpaqueField<T> as StableAbi>::LAYOUT
156}
157
158///////////////////////////////////////////////////////////////////////////////
159
160/////////////////////////////////////////////////////////////////////////////
161////                Implementations
162/////////////////////////////////////////////////////////////////////////////
163
164///////////////////////////////////////////////////////////////////////////////
165
166unsafe impl<T> GetStaticEquivalent_ for PhantomData<T>
167where
168    T: GetStaticEquivalent_,
169{
170    type StaticEquivalent = PhantomData<T::StaticEquivalent>;
171}
172
173unsafe impl<T> StableAbi for PhantomData<T>
174where
175    T: StableAbi,
176{
177    type IsNonZeroType = False;
178
179    const LAYOUT: &'static TypeLayout = {
180        zst_assert!(Self);
181
182        const MONO_TYPE_LAYOUT: &MonoTypeLayout = &MonoTypeLayout::new(
183            *mono_shared_vars,
184            rstr!("PhantomData"),
185            ItemInfo::std_type_in(nulstr_trunc!("std::marker")),
186            MonoTLData::EMPTY,
187            tl_genparams!(;0;),
188            ReprAttr::C,
189            ModReflMode::Module,
190            {
191                const S: &[CompTLField] =
192                    &[CompTLField::std_field(field0, LifetimeRange::EMPTY, 0)];
193                RSlice::from_slice(S)
194            },
195        );
196
197        make_shared_vars! {
198            impl[T] PhantomData<T>
199            where[T: StableAbi];
200
201            let (mono_shared_vars,shared_vars)={
202                strings={ field0:"0", },
203                type_layouts=[T],
204            };
205        }
206
207        &TypeLayout::from_std::<Self>(
208            shared_vars,
209            MONO_TYPE_LAYOUT,
210            Self::ABI_CONSTS,
211            GenericTLData::Struct,
212        )
213    };
214}
215
216macro_rules! phantomdata_tuples {
217    (ignore; $($anything:tt)*)=>{ 1 };
218    (
219        $(($tuple_param:ident,$name_ident:ident=$name_str:literal))*
220    )=>{
221        unsafe impl<$($tuple_param,)*>
222            GetStaticEquivalent_
223        for PhantomData<($($tuple_param,)*)>
224        where
225            $($tuple_param:GetStaticEquivalent_,)*
226        {
227            type StaticEquivalent=PhantomData<($($tuple_param::StaticEquivalent,)*)>;
228        }
229
230        unsafe impl<$($tuple_param,)*>
231            StableAbi
232        for PhantomData<($($tuple_param,)*)>
233        where
234            $($tuple_param:StableAbi,)*
235        {
236            type IsNonZeroType = False;
237
238            const LAYOUT: &'static TypeLayout = {
239                zst_assert!(Self);
240
241                const MONO_TYPE_LAYOUT:&MonoTypeLayout=&MonoTypeLayout::new(
242                    *mono_shared_vars,
243                    rstr!("PhantomData"),
244                    ItemInfo::std_type_in(nulstr_trunc!("std::marker")),
245                    MonoTLData::EMPTY,
246                    tl_genparams!(;0..COUNT;),
247                    ReprAttr::C,
248                    ModReflMode::Module,
249                    unsafe{
250                        RSlice::from_raw_parts_with_lifetime(FIELDS,COUNT)
251                    }
252                );
253
254                #[allow(unused_assignments)]
255                const FIELDS:&'static [CompTLField;COUNT]={
256                    let mut i=0;
257                    $(
258                        #[allow(non_snake_case)]
259                        let $tuple_param=
260                            CompTLField::std_field($name_ident,LifetimeRange::EMPTY,i);
261                        i+=1;
262                    )*
263                    &[$($tuple_param,)*]
264                };
265
266                const COUNT:usize=$(phantomdata_tuples!(ignore;$tuple_param)+)* 0;
267
268                make_shared_vars!{
269                    impl[$($tuple_param,)*] PhantomData<($($tuple_param,)*)>
270                    where[
271                        $($tuple_param:StableAbi,)*
272                    ];
273
274                    let (mono_shared_vars,shared_vars)={
275                        strings={ $($name_ident:$name_str,)* },
276                        type_layouts=[$($tuple_param,)*],
277                    };
278                }
279
280                &TypeLayout::from_std::<Self>(
281                    shared_vars,
282                    MONO_TYPE_LAYOUT,
283                    Self::ABI_CONSTS,
284                    GenericTLData::Struct,
285                )
286            };
287        }
288    }
289}
290
291/*
292fn main(){
293    for i in 1..=16{
294        println!("phantomdata_tuples!{{");
295        for j in 0..i{
296            println!("    (T{0},p{0}=\"{0}\")",j);
297        }
298        println!("}}")
299    }
300}
301*/
302
303phantomdata_tuples! {
304    (T0,p0="0")
305}
306phantomdata_tuples! {
307    (T0,p0="0")
308    (T1,p1="1")
309}
310phantomdata_tuples! {
311    (T0,p0="0")
312    (T1,p1="1")
313    (T2,p2="2")
314}
315phantomdata_tuples! {
316    (T0,p0="0")
317    (T1,p1="1")
318    (T2,p2="2")
319    (T3,p3="3")
320}
321phantomdata_tuples! {
322    (T0,p0="0")
323    (T1,p1="1")
324    (T2,p2="2")
325    (T3,p3="3")
326    (T4,p4="4")
327}
328phantomdata_tuples! {
329    (T0,p0="0")
330    (T1,p1="1")
331    (T2,p2="2")
332    (T3,p3="3")
333    (T4,p4="4")
334    (T5,p5="5")
335}
336phantomdata_tuples! {
337    (T0,p0="0")
338    (T1,p1="1")
339    (T2,p2="2")
340    (T3,p3="3")
341    (T4,p4="4")
342    (T5,p5="5")
343    (T6,p6="6")
344}
345phantomdata_tuples! {
346    (T0,p0="0")
347    (T1,p1="1")
348    (T2,p2="2")
349    (T3,p3="3")
350    (T4,p4="4")
351    (T5,p5="5")
352    (T6,p6="6")
353    (T7,p7="7")
354}
355phantomdata_tuples! {
356    (T0,p0="0")
357    (T1,p1="1")
358    (T2,p2="2")
359    (T3,p3="3")
360    (T4,p4="4")
361    (T5,p5="5")
362    (T6,p6="6")
363    (T7,p7="7")
364    (T8,p8="8")
365}
366phantomdata_tuples! {
367    (T0,p0="0")
368    (T1,p1="1")
369    (T2,p2="2")
370    (T3,p3="3")
371    (T4,p4="4")
372    (T5,p5="5")
373    (T6,p6="6")
374    (T7,p7="7")
375    (T8,p8="8")
376    (T9,p9="9")
377}
378phantomdata_tuples! {
379    (T0,p0="0")
380    (T1,p1="1")
381    (T2,p2="2")
382    (T3,p3="3")
383    (T4,p4="4")
384    (T5,p5="5")
385    (T6,p6="6")
386    (T7,p7="7")
387    (T8,p8="8")
388    (T9,p9="9")
389    (T10,p10="10")
390}
391phantomdata_tuples! {
392    (T0,p0="0")
393    (T1,p1="1")
394    (T2,p2="2")
395    (T3,p3="3")
396    (T4,p4="4")
397    (T5,p5="5")
398    (T6,p6="6")
399    (T7,p7="7")
400    (T8,p8="8")
401    (T9,p9="9")
402    (T10,p10="10")
403    (T11,p11="11")
404}
405phantomdata_tuples! {
406    (T0,p0="0")
407    (T1,p1="1")
408    (T2,p2="2")
409    (T3,p3="3")
410    (T4,p4="4")
411    (T5,p5="5")
412    (T6,p6="6")
413    (T7,p7="7")
414    (T8,p8="8")
415    (T9,p9="9")
416    (T10,p10="10")
417    (T11,p11="11")
418    (T12,p12="12")
419}
420phantomdata_tuples! {
421    (T0,p0="0")
422    (T1,p1="1")
423    (T2,p2="2")
424    (T3,p3="3")
425    (T4,p4="4")
426    (T5,p5="5")
427    (T6,p6="6")
428    (T7,p7="7")
429    (T8,p8="8")
430    (T9,p9="9")
431    (T10,p10="10")
432    (T11,p11="11")
433    (T12,p12="12")
434    (T13,p13="13")
435}
436phantomdata_tuples! {
437    (T0,p0="0")
438    (T1,p1="1")
439    (T2,p2="2")
440    (T3,p3="3")
441    (T4,p4="4")
442    (T5,p5="5")
443    (T6,p6="6")
444    (T7,p7="7")
445    (T8,p8="8")
446    (T9,p9="9")
447    (T10,p10="10")
448    (T11,p11="11")
449    (T12,p12="12")
450    (T13,p13="13")
451    (T14,p14="14")
452}
453phantomdata_tuples! {
454    (T0,p0="0")
455    (T1,p1="1")
456    (T2,p2="2")
457    (T3,p3="3")
458    (T4,p4="4")
459    (T5,p5="5")
460    (T6,p6="6")
461    (T7,p7="7")
462    (T8,p8="8")
463    (T9,p9="9")
464    (T10,p10="10")
465    (T11,p11="11")
466    (T12,p12="12")
467    (T13,p13="13")
468    (T14,p14="14")
469    (T15,p15="15")
470}
471
472unsafe impl GetStaticEquivalent_ for () {
473    type StaticEquivalent = ();
474}
475unsafe impl StableAbi for () {
476    type IsNonZeroType = False;
477
478    const LAYOUT: &'static TypeLayout = {
479        const MONO_TYPE_LAYOUT: &MonoTypeLayout = &MonoTypeLayout::new(
480            *mono_shared_vars,
481            rstr!("()"),
482            ItemInfo::primitive(),
483            MonoTLData::EMPTY,
484            tl_genparams!(;;),
485            ReprAttr::C,
486            ModReflMode::Module,
487            RSlice::EMPTY,
488        );
489
490        make_shared_vars! {
491            impl[] ();
492
493            let (mono_shared_vars,shared_vars)={};
494        }
495
496        &TypeLayout::from_std::<Self>(
497            shared_vars,
498            MONO_TYPE_LAYOUT,
499            Self::ABI_CONSTS,
500            GenericTLData::Struct,
501        )
502    };
503}
504
505/////////////
506
507unsafe impl<'a, T> GetStaticEquivalent_ for &'a T
508where
509    T: 'a + GetStaticEquivalent_,
510{
511    type StaticEquivalent = &'static T::StaticEquivalent;
512}
513
514// Does not allow ?Sized types because the DST fat pointer does not have a stable layout.
515unsafe impl<'a, T> StableAbi for &'a T
516where
517    T: 'a + StableAbi,
518{
519    type IsNonZeroType = True;
520
521    const LAYOUT: &'static TypeLayout = {
522        const MONO_TYPE_LAYOUT: &MonoTypeLayout = &MonoTypeLayout::new(
523            *mono_shared_vars,
524            rstr!("&"),
525            ItemInfo::primitive(),
526            MonoTLData::Primitive(TLPrimitive::SharedRef),
527            tl_genparams!('a;0;),
528            ReprAttr::Primitive,
529            ModReflMode::DelegateDeref { layout_index: 0 },
530            {
531                const S: &[CompTLField] =
532                    &[CompTLField::std_field(field0, LifetimeRange::EMPTY, 0)];
533                RSlice::from_slice(S)
534            },
535        );
536
537        make_shared_vars! {
538            impl['a, T] &'a T
539            where[ T: 'a + StableAbi];
540
541            let (mono_shared_vars,shared_vars)={
542                strings={ field0:"0", },
543                type_layouts=[T],
544            };
545        }
546
547        &TypeLayout::from_std::<Self>(
548            shared_vars,
549            MONO_TYPE_LAYOUT,
550            Self::ABI_CONSTS,
551            GenericTLData::Primitive,
552        )
553    };
554}
555
556unsafe impl<'a, T> GetStaticEquivalent_ for &'a mut T
557where
558    T: 'a + GetStaticEquivalent_,
559{
560    type StaticEquivalent = &'static mut T::StaticEquivalent;
561}
562
563// Does not allow ?Sized types because the DST fat pointer does not have a stable layout.
564unsafe impl<'a, T> StableAbi for &'a mut T
565where
566    T: 'a + StableAbi,
567{
568    type IsNonZeroType = True;
569
570    const LAYOUT: &'static TypeLayout = {
571        const MONO_TYPE_LAYOUT: &MonoTypeLayout = &MonoTypeLayout::new(
572            *mono_shared_vars,
573            rstr!("&mut"),
574            ItemInfo::primitive(),
575            MonoTLData::Primitive(TLPrimitive::MutRef),
576            tl_genparams!('a;0;),
577            ReprAttr::Primitive,
578            ModReflMode::DelegateDeref { layout_index: 0 },
579            {
580                const S: &[CompTLField] =
581                    &[CompTLField::std_field(field0, LifetimeRange::EMPTY, 0)];
582                RSlice::from_slice(S)
583            },
584        );
585
586        make_shared_vars! {
587            impl['a, T] &'a mut T
588            where[ T: 'a + StableAbi];
589
590            let (mono_shared_vars,shared_vars)={
591                strings={ field0:"0", },
592                type_layouts=[T],
593            };
594        }
595
596        &TypeLayout::from_std::<Self>(
597            shared_vars,
598            MONO_TYPE_LAYOUT,
599            Self::ABI_CONSTS,
600            GenericTLData::Primitive,
601        )
602    };
603}
604
605unsafe impl<T> GetStaticEquivalent_ for NonNull<T>
606where
607    T: GetStaticEquivalent_,
608{
609    type StaticEquivalent = NonNull<T::StaticEquivalent>;
610}
611
612// Does not allow ?Sized types because the DST fat pointer does not have a stable layout.
613unsafe impl<T> StableAbi for NonNull<T>
614where
615    T: StableAbi,
616{
617    type IsNonZeroType = True;
618
619    const LAYOUT: &'static TypeLayout = {
620        const MONO_TYPE_LAYOUT: &MonoTypeLayout = &MonoTypeLayout::new(
621            *mono_shared_vars,
622            rstr!("NonNull"),
623            ItemInfo::std_type_in(nulstr_trunc!("std::ptr")),
624            {
625                const S: &[CompTLField] =
626                    &[CompTLField::std_field(field0, LifetimeRange::EMPTY, 1)];
627                MonoTLData::struct_(RSlice::from_slice(S))
628            },
629            tl_genparams!(;0;),
630            ReprAttr::Transparent,
631            ModReflMode::Module,
632            RSlice::EMPTY,
633        );
634
635        make_shared_vars! {
636            impl[T] NonNull<T>
637            where[ T: StableAbi];
638
639            let (mono_shared_vars,shared_vars)={
640                strings={ field0:"0", },
641                type_layouts=[T,*const T],
642            };
643        }
644
645        &TypeLayout::from_std::<Self>(
646            shared_vars,
647            MONO_TYPE_LAYOUT,
648            Self::ABI_CONSTS,
649            GenericTLData::Struct,
650        )
651    };
652}
653
654unsafe impl<T> GetStaticEquivalent_ for AtomicPtr<T>
655where
656    T: GetStaticEquivalent_,
657{
658    type StaticEquivalent = AtomicPtr<T::StaticEquivalent>;
659}
660
661unsafe impl<T> StableAbi for AtomicPtr<T>
662where
663    T: StableAbi,
664{
665    type IsNonZeroType = False;
666
667    const LAYOUT: &'static TypeLayout = {
668        const MONO_TYPE_LAYOUT: &MonoTypeLayout = &MonoTypeLayout::new(
669            *mono_shared_vars,
670            rstr!("AtomicPtr"),
671            ItemInfo::std_type_in(nulstr_trunc!("std::sync::atomic")),
672            {
673                const S: &[CompTLField] =
674                    &[CompTLField::std_field(field0, LifetimeRange::EMPTY, 1)];
675                MonoTLData::struct_(RSlice::from_slice(S))
676            },
677            tl_genparams!(;0;),
678            ReprAttr::Transparent,
679            ModReflMode::Module,
680            RSlice::EMPTY,
681        );
682
683        make_shared_vars! {
684            impl[T] AtomicPtr<T>
685            where[T: StableAbi];
686
687            let (mono_shared_vars,shared_vars)={
688                strings={ field0:"0", },
689                type_layouts=[T,*mut T],
690            };
691        }
692
693        &TypeLayout::from_std::<Self>(
694            shared_vars,
695            MONO_TYPE_LAYOUT,
696            Self::ABI_CONSTS,
697            GenericTLData::Struct,
698        )
699    };
700}
701
702unsafe impl<T> GetStaticEquivalent_ for *const T
703where
704    T: GetStaticEquivalent_,
705{
706    type StaticEquivalent = *const T::StaticEquivalent;
707}
708// Does not allow ?Sized types because the DST fat pointer does not have a stable layout.
709unsafe impl<T> StableAbi for *const T
710where
711    T: StableAbi,
712{
713    type IsNonZeroType = False;
714
715    const LAYOUT: &'static TypeLayout = {
716        const MONO_TYPE_LAYOUT: &MonoTypeLayout = &MonoTypeLayout::new(
717            *mono_shared_vars,
718            rstr!("*const"),
719            ItemInfo::primitive(),
720            MonoTLData::Primitive(TLPrimitive::ConstPtr),
721            tl_genparams!(;0;),
722            ReprAttr::Primitive,
723            ModReflMode::Module,
724            {
725                const S: &[CompTLField] =
726                    &[CompTLField::std_field(field0, LifetimeRange::EMPTY, 0)];
727                RSlice::from_slice(S)
728            },
729        );
730
731        make_shared_vars! {
732            impl[T] *const T
733            where[T: StableAbi];
734
735            let (mono_shared_vars,shared_vars)={
736                strings={ field0:"0", },
737                type_layouts=[T],
738            };
739        }
740
741        &TypeLayout::from_std::<Self>(
742            shared_vars,
743            MONO_TYPE_LAYOUT,
744            Self::ABI_CONSTS,
745            GenericTLData::Primitive,
746        )
747    };
748}
749
750unsafe impl<T> GetStaticEquivalent_ for *mut T
751where
752    T: GetStaticEquivalent_,
753{
754    type StaticEquivalent = *mut T::StaticEquivalent;
755}
756// Does not allow ?Sized types because the DST fat pointer does not have a stable layout.
757unsafe impl<T> StableAbi for *mut T
758where
759    T: StableAbi,
760{
761    type IsNonZeroType = False;
762
763    const LAYOUT: &'static TypeLayout = {
764        const MONO_TYPE_LAYOUT: &MonoTypeLayout = &MonoTypeLayout::new(
765            *mono_shared_vars,
766            rstr!("*mut"),
767            ItemInfo::primitive(),
768            MonoTLData::Primitive(TLPrimitive::MutPtr),
769            tl_genparams!(;0;),
770            ReprAttr::Primitive,
771            ModReflMode::Module,
772            {
773                const S: &[CompTLField] =
774                    &[CompTLField::std_field(field0, LifetimeRange::EMPTY, 0)];
775                RSlice::from_slice(S)
776            },
777        );
778
779        make_shared_vars! {
780            impl[T] *mut T
781            where[T: StableAbi];
782
783            let (mono_shared_vars,shared_vars)={
784                strings={ field0:"0", },
785                type_layouts=[T],
786            };
787        }
788
789        &TypeLayout::from_std::<Self>(
790            shared_vars,
791            MONO_TYPE_LAYOUT,
792            Self::ABI_CONSTS,
793            GenericTLData::Primitive,
794        )
795    };
796}
797
798/////////////
799
800macro_rules! impl_stable_abi_array {
801    () => {
802        unsafe impl<T, const N: usize> GetStaticEquivalent_ for [T; N]
803        where
804            T: GetStaticEquivalent_,
805        {
806            type StaticEquivalent = [T::StaticEquivalent; N];
807        }
808
809        unsafe impl<T, const N: usize> StableAbi for [T; N]
810        where
811            T: StableAbi,
812        {
813            type IsNonZeroType = False;
814
815            const LAYOUT: &'static TypeLayout = {
816                // Used to get constants for [T; N]  where T doesn't matter
817                struct ArrayMonoConsts<const N: usize>;
818
819                impl<const N: usize> ArrayMonoConsts<N> {
820                    const MONO_TYPE_LAYOUT: &'static MonoTypeLayout = &MonoTypeLayout::new(
821                        *mono_shared_vars,
822                        rstr!("array"),
823                        ItemInfo::primitive(),
824                        MonoTLData::Primitive(TLPrimitive::Array),
825                        tl_genparams!(;0;0),
826                        ReprAttr::Primitive,
827                        ModReflMode::Module,
828                        {
829                            const S: &[CompTLField] =
830                                &[CompTLField::std_field(field0, LifetimeRange::EMPTY, 0)];
831                            RSlice::from_slice(S)
832                        },
833                    );
834                }
835
836                make_shared_vars! {
837                    impl[T, const N: usize] [T; N]
838                    where[T: StableAbi];
839
840                    let (mono_shared_vars,shared_vars)={
841                        strings={ field0:"element", },
842                        type_layouts=[T],
843                        constant=[usize => N],
844                    };
845                }
846
847                &TypeLayout::from_std::<Self>(
848                    shared_vars,
849                    ArrayMonoConsts::<N>::MONO_TYPE_LAYOUT,
850                    Self::ABI_CONSTS,
851                    GenericTLData::Primitive,
852                )
853            };
854        }
855    };
856}
857
858impl_stable_abi_array! {}
859
860/////////////
861
862unsafe impl<T> GetStaticEquivalent_ for Option<T>
863where
864    T: GetStaticEquivalent_,
865{
866    type StaticEquivalent = Option<T::StaticEquivalent>;
867}
868/// Implementing abi stability for `Option<T>` is fine if
869/// T is a NonZero primitive type.
870unsafe impl<T> StableAbi for Option<T>
871where
872    T: StableAbi<IsNonZeroType = True>,
873{
874    type IsNonZeroType = False;
875
876    const LAYOUT: &'static TypeLayout = {
877        const MONO_TYPE_LAYOUT: &MonoTypeLayout = &MonoTypeLayout::new(
878            *mono_shared_vars,
879            rstr!("Option"),
880            ItemInfo::std_type_in(nulstr_trunc!("std::option")),
881            MonoTLData::Enum(MonoTLEnum::new(variant_names, rslice![1, 0], {
882                const S: &[CompTLField] =
883                    &[CompTLField::std_field(field0, LifetimeRange::EMPTY, 0)];
884                CompTLFields::from_fields(RSlice::from_slice(S))
885            })),
886            tl_genparams!(;0;),
887            ReprAttr::OptionNonZero,
888            ModReflMode::Module,
889            RSlice::EMPTY,
890        );
891
892        make_shared_vars! {
893            impl[T] Option<T>
894            where [ T: StableAbi<IsNonZeroType = True>, ];
895
896            let (mono_shared_vars,shared_vars)={
897                strings={
898                    variant_names:"Some;None;",
899                    field0:"0",
900                },
901                type_layouts=[T],
902            };
903        }
904
905        &TypeLayout::from_std::<Self>(
906            shared_vars,
907            MONO_TYPE_LAYOUT,
908            Self::ABI_CONSTS,
909            GenericTLData::Enum(GenericTLEnum::exhaustive(TLDiscriminants::from_u8_slice(
910                rslice![0, 1],
911            ))),
912        )
913    };
914}
915
916/////////////
917
918macro_rules! impl_for_primitive_ints {
919    (
920        $( ($type:ty,$type_name:literal,$tl_primitive:expr) ,)*
921    ) => (
922        $(
923            unsafe impl GetStaticEquivalent_ for $type {
924                type StaticEquivalent=Self;
925            }
926            unsafe impl StableAbi for $type {
927                type IsNonZeroType=False;
928
929                const LAYOUT: &'static TypeLayout = {
930                    const MONO_TYPE_LAYOUT:&MonoTypeLayout=&MonoTypeLayout::new(
931                        *mono_shared_vars,
932                        rstr!($type_name),
933                        ItemInfo::primitive(),
934                        MonoTLData::Primitive($tl_primitive),
935                        tl_genparams!(;;),
936                        ReprAttr::Primitive,
937                        ModReflMode::Module,
938                        RSlice::EMPTY,
939                    );
940
941                    make_shared_vars!{
942                        impl[] $type;
943
944                        let (mono_shared_vars,shared_vars)={
945                            type_layouts=[],
946                        };
947                    }
948
949                    &TypeLayout::from_std::<Self>(
950                        shared_vars,
951                        MONO_TYPE_LAYOUT,
952                        Self::ABI_CONSTS,
953                        GenericTLData::Primitive,
954                    )
955                };
956            }
957        )*
958    )
959}
960
961impl_for_primitive_ints! {
962    (u8   ,"u8"   ,TLPrimitive::U8),
963    (i8   ,"i8"   ,TLPrimitive::I8),
964    (u16  ,"u16"  ,TLPrimitive::U16),
965    (i16  ,"i16"  ,TLPrimitive::I16),
966    (u32  ,"u32"  ,TLPrimitive::U32),
967    (i32  ,"i32"  ,TLPrimitive::I32),
968    (u64  ,"u64"  ,TLPrimitive::U64),
969    (i64  ,"i64"  ,TLPrimitive::I64),
970    (usize,"usize",TLPrimitive::Usize),
971    (isize,"isize",TLPrimitive::Isize),
972    (bool ,"bool" ,TLPrimitive::Bool),
973    (f32 ,"f32" ,TLPrimitive::F32),
974    (f64 ,"f64" ,TLPrimitive::F64),
975}
976
977macro_rules! impl_for_concrete {
978    (
979        type IsNonZeroType=$zeroness:ty;
980        [
981            $( ($this:ty,$this_name:literal,$prim_repr:ty,$in_mod:expr) ,)*
982        ]
983    ) => (
984        $(
985            unsafe impl GetStaticEquivalent_ for $this {
986                type StaticEquivalent=Self;
987            }
988            unsafe impl StableAbi for $this {
989                type IsNonZeroType=$zeroness;
990
991                const LAYOUT: &'static TypeLayout = {
992                    const MONO_TYPE_LAYOUT:&MonoTypeLayout=&MonoTypeLayout::new(
993                        *mono_shared_vars,
994                        rstr!($this_name),
995                        ItemInfo::std_type_in(nulstr_trunc!($in_mod)),
996                        {
997                            const S: &[CompTLField] = &[
998                                CompTLField::std_field(field0,LifetimeRange::EMPTY,0),
999                            ];
1000                            MonoTLData::struct_(RSlice::from_slice(S))
1001                        },
1002                        tl_genparams!(;;),
1003                        ReprAttr::Transparent,
1004                        ModReflMode::Module,
1005                        RSlice::EMPTY,
1006                    );
1007
1008                    make_shared_vars!{
1009                        impl[] $this;
1010
1011                        let (mono_shared_vars,shared_vars)={
1012                            strings={ field0:"0" },
1013                            type_layouts=[$prim_repr],
1014                        };
1015                    }
1016
1017                    &TypeLayout::from_std::<Self>(
1018                        shared_vars,
1019                        MONO_TYPE_LAYOUT,
1020                        Self::ABI_CONSTS,
1021                        GenericTLData::Struct,
1022                    )
1023                };
1024            }
1025        )*
1026    )
1027}
1028
1029impl_for_concrete! {
1030    type IsNonZeroType=False;
1031    [
1032        (AtomicBool ,"AtomicBool" ,bool,"std::sync::atomic"),
1033        (AtomicIsize,"AtomicIsize",isize,"std::sync::atomic"),
1034        (AtomicUsize,"AtomicUsize",usize,"std::sync::atomic"),
1035    ]
1036}
1037
1038impl_for_concrete! {
1039    type IsNonZeroType=True;
1040    [
1041        (NonZeroU8   ,"NonZeroU8"   ,u8,"std::num"),
1042        (NonZeroU16  ,"NonZeroU16"  ,u16,"std::num"),
1043        (NonZeroU32  ,"NonZeroU32"  ,u32,"std::num"),
1044        (NonZeroU64  ,"NonZeroU64"  ,u64,"std::num"),
1045        (NonZeroUsize,"NonZeroUsize",usize,"std::num"),
1046    ]
1047}
1048/////////////
1049
1050mod rust_1_34_impls {
1051    use super::*;
1052    use core::num::*;
1053    use std::sync::atomic::*;
1054
1055    impl_for_concrete! {
1056        type IsNonZeroType=False;
1057        [
1058            (AtomicI8 ,"AtomicI8" ,i8,"std::sync::atomic"),
1059            (AtomicI16,"AtomicI16",i16,"std::sync::atomic"),
1060            (AtomicI32,"AtomicI32",i32,"std::sync::atomic"),
1061            (AtomicI64,"AtomicI64",i64,"std::sync::atomic"),
1062            (AtomicU8 ,"AtomicU8" ,u8,"std::sync::atomic"),
1063            (AtomicU16,"AtomicU16",u16,"std::sync::atomic"),
1064            (AtomicU32,"AtomicU32",u32,"std::sync::atomic"),
1065            (AtomicU64,"AtomicU64",u64,"std::sync::atomic"),
1066        ]
1067    }
1068
1069    impl_for_concrete! {
1070        type IsNonZeroType=True;
1071        [
1072            (NonZeroI8   ,"NonZeroI8"   ,i8,"core::num"),
1073            (NonZeroI16  ,"NonZeroI16"  ,i16,"core::num"),
1074            (NonZeroI32  ,"NonZeroI32"  ,i32,"core::num"),
1075            (NonZeroI64  ,"NonZeroI64"  ,i64,"core::num"),
1076            (NonZeroIsize,"NonZeroIsize",isize,"core::num"),
1077        ]
1078    }
1079}
1080
1081mod rust_1_36_impls {
1082    use super::*;
1083    use std::mem::MaybeUninit;
1084
1085    unsafe impl<T> GetStaticEquivalent_ for MaybeUninit<T>
1086    where
1087        T: GetStaticEquivalent_,
1088    {
1089        type StaticEquivalent = MaybeUninit<T::StaticEquivalent>;
1090    }
1091    unsafe impl<T> StableAbi for MaybeUninit<T>
1092    where
1093        T: StableAbi,
1094    {
1095        // MaybeUninit blocks layout optimizations.
1096        type IsNonZeroType = False;
1097
1098        const LAYOUT: &'static TypeLayout = {
1099            const MONO_TYPE_LAYOUT: &MonoTypeLayout = &MonoTypeLayout::new(
1100                *mono_shared_vars,
1101                rstr!("MaybeUninit"),
1102                ItemInfo::std_type_in(nulstr_trunc!("std::mem")),
1103                {
1104                    const S: &[CompTLField] =
1105                        &[CompTLField::std_field(field0, LifetimeRange::EMPTY, 0)];
1106                    MonoTLData::struct_(RSlice::from_slice(S))
1107                },
1108                tl_genparams!(;0;),
1109                // Using `ReprAttr::Transparent` so that if I add C header file translation
1110                // it will be translated to just `T`.
1111                ReprAttr::Transparent,
1112                ModReflMode::Opaque,
1113                RSlice::EMPTY,
1114            );
1115
1116            make_shared_vars! {
1117                impl[T] MaybeUninit<T>
1118                where [T: StableAbi];
1119
1120                let (mono_shared_vars,shared_vars)={
1121                    strings={ field0:"value" },
1122                    type_layouts=[T],
1123                };
1124            }
1125
1126            &TypeLayout::from_std::<Self>(
1127                shared_vars,
1128                MONO_TYPE_LAYOUT,
1129                Self::ABI_CONSTS,
1130                GenericTLData::Struct,
1131            )
1132        };
1133    }
1134}
1135
1136/////////////
1137
1138macro_rules! impl_sabi_for_newtype {
1139    (@trans transparent)=>{ P::IsNonZeroType };
1140    (@trans C)=>{ False };
1141    (
1142        $type_constr:ident
1143        $(where[ $($where_clause:tt)* ])* ,
1144        $transparency:ident,
1145        $type_name:literal,
1146        $mod_path:expr
1147    ) => (
1148        unsafe impl<P> GetStaticEquivalent_ for $type_constr<P>
1149        where
1150            P: GetStaticEquivalent_,
1151            $($($where_clause)*)*
1152        {
1153            type StaticEquivalent=$type_constr<P::StaticEquivalent>;
1154        }
1155        unsafe impl<P> StableAbi for $type_constr<P>
1156        where
1157            P: StableAbi,
1158            $($($where_clause)*)*
1159        {
1160            type IsNonZeroType = impl_sabi_for_newtype!(@trans $transparency);
1161
1162            const LAYOUT: &'static TypeLayout = {
1163                const MONO_TYPE_LAYOUT:&MonoTypeLayout=&MonoTypeLayout::new(
1164                    *mono_shared_vars,
1165                    rstr!($type_name),
1166                    ItemInfo::std_type_in(nulstr_trunc!($mod_path)),
1167                    {
1168                        const S: &[CompTLField] = &[
1169                            CompTLField::std_field(field0,LifetimeRange::EMPTY,0),
1170                        ];
1171                        MonoTLData::struct_(RSlice::from_slice(S))
1172                    },
1173                    tl_genparams!(;0;),
1174                    ReprAttr::Transparent,
1175                    ModReflMode::Module,
1176                    RSlice::EMPTY,
1177                );
1178
1179                make_shared_vars!{
1180                    impl[P]  $type_constr<P>
1181                    where [
1182                        P: StableAbi,
1183                        $($($where_clause)*)*
1184                    ];
1185
1186                    let (mono_shared_vars,shared_vars)={
1187                        strings={ field0:"0" },
1188                        type_layouts=[P],
1189                    };
1190                }
1191
1192                &TypeLayout::from_std::<Self>(
1193                    shared_vars,
1194                    MONO_TYPE_LAYOUT,
1195                    Self::ABI_CONSTS,
1196                    GenericTLData::Struct,
1197                )
1198            };
1199        }
1200    )
1201}
1202
1203impl_sabi_for_newtype! { Wrapping    ,transparent,"Wrapping"    ,"std::num" }
1204impl_sabi_for_newtype! { Pin         ,transparent,"Pin"         ,"std::pin" }
1205impl_sabi_for_newtype! { ManuallyDrop,transparent,"ManuallyDrop","std::mem" }
1206
1207impl_sabi_for_newtype! { Cell        ,C,"Cell"        ,"std::cell" }
1208impl_sabi_for_newtype! { UnsafeCell  ,C,"UnsafeCell"  ,"std::cell" }
1209
1210/////////////
1211
1212macro_rules! impl_stableabi_for_unit_struct {
1213    (
1214        $type_constr:ident,
1215        $type_name:literal,
1216        $item_info:expr
1217    ) => {
1218        unsafe impl GetStaticEquivalent_ for $type_constr {
1219            type StaticEquivalent = $type_constr;
1220        }
1221        unsafe impl StableAbi for $type_constr {
1222            type IsNonZeroType = False;
1223
1224            const LAYOUT: &'static TypeLayout = {
1225                const MONO_TYPE_LAYOUT: &MonoTypeLayout = &MonoTypeLayout::new(
1226                    *mono_shared_vars,
1227                    rstr!($type_name),
1228                    $item_info,
1229                    MonoTLData::struct_(RSlice::EMPTY),
1230                    tl_genparams!(;;),
1231                    ReprAttr::C,
1232                    ModReflMode::Module,
1233                    RSlice::EMPTY,
1234                );
1235
1236                make_shared_vars! {
1237                    impl[] $type_constr;
1238
1239                    let (mono_shared_vars,shared_vars)={};
1240                }
1241
1242                &TypeLayout::from_std::<Self>(
1243                    shared_vars,
1244                    MONO_TYPE_LAYOUT,
1245                    Self::ABI_CONSTS,
1246                    GenericTLData::Struct,
1247                )
1248            };
1249        }
1250    };
1251}
1252
1253impl_stableabi_for_unit_struct! {
1254    PhantomPinned,"PhantomPinned",ItemInfo::std_type_in(nulstr_trunc!("std::marker"))
1255}
1256
1257/////////////
1258
1259unsafe impl GetStaticEquivalent_ for ::core::ffi::c_void {
1260    type StaticEquivalent = ::core::ffi::c_void;
1261}
1262unsafe impl StableAbi for ::core::ffi::c_void {
1263    type IsNonZeroType = False;
1264
1265    const LAYOUT: &'static TypeLayout = {
1266        const MONO_TYPE_LAYOUT: &MonoTypeLayout = &MonoTypeLayout::new(
1267            *mono_shared_vars,
1268            rstr!("c_void"),
1269            ItemInfo::std_type_in(nulstr_trunc!("std::ffi")),
1270            MonoTLData::EMPTY,
1271            tl_genparams!(;;),
1272            ReprAttr::C,
1273            ModReflMode::Module,
1274            RSlice::EMPTY,
1275        );
1276
1277        make_shared_vars! {
1278            impl[] ::core::ffi::c_void;
1279
1280            let (mono_shared_vars,shared_vars)={};
1281        }
1282
1283        &TypeLayout::from_std::<Self>(
1284            shared_vars,
1285            MONO_TYPE_LAYOUT,
1286            Self::ABI_CONSTS,
1287            GenericTLData::Struct,
1288        )
1289    };
1290}
1291
1292/////////////
1293
1294unsafe impl GetStaticEquivalent_ for core_extensions::Void {
1295    type StaticEquivalent = Self;
1296}
1297unsafe impl StableAbi for core_extensions::Void {
1298    type IsNonZeroType = False;
1299
1300    const LAYOUT: &'static TypeLayout = {
1301        const MONO_TYPE_LAYOUT: &MonoTypeLayout = &MonoTypeLayout::new(
1302            *mono_shared_vars,
1303            rstr!("Void"),
1304            ItemInfo::package_and_mod("core_extensions;0.0.0", nulstr_trunc!("core_extensions")),
1305            MonoTLData::Enum(MonoTLEnum::new(
1306                StartLen::EMPTY,
1307                RSlice::EMPTY,
1308                CompTLFields::EMPTY,
1309            )),
1310            tl_genparams!(;;),
1311            ReprAttr::Int(DiscriminantRepr::U8),
1312            ModReflMode::Module,
1313            RSlice::EMPTY,
1314        );
1315
1316        make_shared_vars! {
1317            impl[] core_extensions::Void;
1318
1319            let (mono_shared_vars,shared_vars)={};
1320        }
1321
1322        &TypeLayout::from_std::<Self>(
1323            shared_vars,
1324            MONO_TYPE_LAYOUT,
1325            Self::ABI_CONSTS,
1326            GenericTLData::Enum(GenericTLEnum::exhaustive(TLDiscriminants::from_u8_slice(
1327                RSlice::EMPTY,
1328            ))),
1329        )
1330    };
1331}
1332
1333/////////////
1334
1335/// The layout of `extern "C" fn()` and `unsafe extern "C" fn()`
1336macro_rules! empty_extern_fn_layout {
1337    ($this:ty) => {{
1338        make_shared_vars! {
1339            impl[] $this;
1340
1341            let (mono_shared_vars,shared_vars)={};
1342        }
1343        const MONO_TL_EXTERN_FN: &'static MonoTypeLayout = &MonoTypeLayout::new(
1344            *mono_shared_vars,
1345            rstr!("AFunctionPointer"),
1346            make_item_info!(),
1347            MonoTLData::Opaque,
1348        tl_genparams!(;;),
1349            ReprAttr::C,
1350            ModReflMode::Opaque,
1351            RSlice::EMPTY,
1352        );
1353
1354        &TypeLayout::from_std::<Self>(
1355            shared_vars,
1356            MONO_TL_EXTERN_FN,
1357            Self::ABI_CONSTS,
1358            GenericTLData::Opaque,
1359        )
1360    }};
1361}
1362
1363/// This is the only function type that implements StableAbi
1364/// so as to make it more obvious that functions involving lifetimes
1365/// cannot implement this trait directly (because of higher ranked trait bounds).
1366unsafe impl GetStaticEquivalent_ for extern "C" fn() {
1367    type StaticEquivalent = Self;
1368}
1369unsafe impl StableAbi for extern "C" fn() {
1370    type IsNonZeroType = True;
1371
1372    const LAYOUT: &'static TypeLayout = empty_extern_fn_layout!(extern "C" fn());
1373}
1374
1375/// This is the only function type that implements StableAbi
1376/// so as to make it more obvious that functions involving lifetimes
1377/// cannot implement this trait directly (because of higher ranked trait bounds).
1378unsafe impl GetStaticEquivalent_ for unsafe extern "C" fn() {
1379    type StaticEquivalent = Self;
1380}
1381unsafe impl StableAbi for unsafe extern "C" fn() {
1382    type IsNonZeroType = True;
1383
1384    const LAYOUT: &'static TypeLayout = empty_extern_fn_layout!(unsafe extern "C" fn());
1385}
1386
1387/// A function that returns the TypeLayout of an `unsafe extern "C" fn()`
1388#[doc(hidden)]
1389pub const UNSAFE_EXTERN_FN_LAYOUT: extern "C" fn() -> &'static TypeLayout =
1390    get_type_layout::<unsafe extern "C" fn()>;
1391
1392/// A function that returns the TypeLayout of an `extern "C" fn()`
1393#[doc(hidden)]
1394pub const EXTERN_FN_LAYOUT: extern "C" fn() -> &'static TypeLayout =
1395    get_type_layout::<extern "C" fn()>;
1396
1397/////////////
1398
1399/// Allows one to create the `TypeLayout` for any type `T`,
1400/// by pretending that it is a primitive type.
1401///
1402/// Used by the StableAbi derive macro by fields marker as `#[sabi(unsafe_opaque_field)]`.
1403///
1404/// # Safety
1405///
1406/// You must ensure that the layout of `T` is compatible through other means.
1407#[repr(transparent)]
1408pub struct UnsafeOpaqueField<T>(T);
1409
1410unsafe impl<T> GetStaticEquivalent_ for UnsafeOpaqueField<T> {
1411    /// it is fine to use `()` because this type is treated as opaque anyway.
1412    type StaticEquivalent = ();
1413}
1414unsafe impl<T> StableAbi for UnsafeOpaqueField<T> {
1415    type IsNonZeroType = False;
1416
1417    const LAYOUT: &'static TypeLayout = {
1418        const MONO_TYPE_LAYOUT: &MonoTypeLayout = &MonoTypeLayout::new(
1419            *mono_shared_vars,
1420            rstr!("OpaqueField"),
1421            make_item_info!(),
1422            MonoTLData::Opaque,
1423            tl_genparams!(;;),
1424            ReprAttr::C,
1425            ModReflMode::Module,
1426            RSlice::EMPTY,
1427        );
1428
1429        make_shared_vars! {
1430            impl[T] UnsafeOpaqueField<T>;
1431
1432            let (mono_shared_vars,shared_vars)={};
1433        }
1434
1435        &TypeLayout::from_std::<Self>(
1436            shared_vars,
1437            MONO_TYPE_LAYOUT,
1438            Self::ABI_CONSTS,
1439            GenericTLData::Opaque,
1440        )
1441    };
1442}
1443
1444/// Allows one to ensure that a `T` implements `StableAbi`,
1445/// while storing an opaque layout instead of `<T as StableAbi>::LAYOUT`.
1446///
1447/// Used by the `StableAbi` derive macro by fields marker as `#[sabi(unsafe_sabi_opaque_field)]`.
1448///
1449/// # Safety
1450///
1451/// You must ensure that the layout of `T` is compatible through other means.
1452#[repr(transparent)]
1453pub struct SabiUnsafeOpaqueField<T>(T);
1454
1455unsafe impl<T> GetStaticEquivalent_ for SabiUnsafeOpaqueField<T> {
1456    /// it is fine to use `()` because this type is treated as opaque anyway.
1457    type StaticEquivalent = ();
1458}
1459unsafe impl<T> StableAbi for SabiUnsafeOpaqueField<T>
1460where
1461    T: StableAbi,
1462{
1463    type IsNonZeroType = False;
1464
1465    const LAYOUT: &'static TypeLayout = { <UnsafeOpaqueField<T>>::LAYOUT };
1466}
1467
1468/////////////