safer_ffi/layout/
impls.rs

1#![cfg_attr(rustfmt, rustfmt::skip)]
2use super::*;
3
4#[cfg(not(any(target_arch = "wasm32", not(feature = "std"))))] // no libc on WASM nor no_std
5const_assert! {
6    ::core::mem::size_of::<crate::libc::uintptr_t>()
7    ==
8    ::core::mem::size_of::<crate::libc::size_t>()
9}
10
11const _: () = { macro_rules! impl_CTypes {
12    () => (
13        impl_CTypes! { @pointers }
14        impl_CTypes! { @zsts }
15        impl_CTypes! { @floats
16            unsafe
17            f32 => "float",
18
19            unsafe
20            f64 => "double",
21        }
22        impl_CTypes! { @integers
23            // C# safety: equivalence based onhttps://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/built-in-types
24
25            unsafe // Safety: trivial integer equivalence.
26            u8 => "uint8" "byte",
27
28            unsafe // Safety: trivial integer equivalence.
29            u16 => "uint16" "UInt16",
30
31            unsafe // Safety: trivial integer equivalence.
32            u32 => "uint32" "UInt32",
33
34            unsafe // Safety: trivial integer equivalence.
35            u64 => "uint64" "UInt64",
36
37            // unsafe u128 => "uint128",
38
39            unsafe // Safety: Contrary to what most people think,
40                   // `usize` is not a `size_t` but an `uintptr_t`,
41                   // since it has a guaranteed non-`unsafe` transmute (`as`)
42                   // with pointers.
43                   //
44                   // That being said, many places where Rust uses `usize`
45                   // C would expect a `size_t` instead, so there is definitely
46                   // a confusion going on with Rust in that regard.
47                   //
48                   // In practice, it looks like Rust will therefore never
49                   // support a platform where `size_t != uintptr_t`.
50                   //
51                   // Given that, and given how `size_t` for, for instance,
52                   // slice lengths, feels far more natural and idiomatic,
53                   // this crate makes the opinionated choice not to support
54                   // such a platform, so as to use `size_t` instead.
55                   //
56                   // To ensure soundness in case Rust were to support such as
57                   // platform, a compile-time assertion is added, that
58                   // ensure the crate will not compile on such platforms.
59                   // (search for `size_of` in this file).
60            usize => "size" "UIntPtr",
61
62
63            unsafe // Safety: trivial integer equivalence.
64            i8 => "int8" "sbyte",
65
66            unsafe // Safety: trivial integer equivalence.
67            i16 => "int16" "Int16",
68
69            unsafe // Safety: trivial integer equivalence.
70            i32 => "int32" "Int32",
71
72            unsafe // Safety: trivial integer equivalence.
73            i64 => "int64" "Int64",
74
75            // unsafe i128 => "int128",
76
77            unsafe // Safety: See `usize`'s
78            isize => "ssize" "IntPtr",
79        }
80        #[cfg(docs)] impl_CTypes! { @fns (A1, A2) } #[cfg(not(docs))]
81        impl_CTypes! { @fns
82            (A10, A9, A8, A7, A6, A5, A4, A3, A2, A1)
83        }
84        #[cfg(docs)] impl_CTypes! { @arrays 1 2 } #[cfg(not(docs))]
85        impl_CTypes! { @arrays
86            // 0
87            1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
88            26 27 28 29 30 31 32 40 48 50 60 64 70 75 80 90 96 100 125 128 192
89            200 250 256 300 400 500 512 600 700 750 800 900 1000 1024
90        }
91    );
92
93    (
94        @arrays
95        $($N:tt)*
96    ) => ($(
97        // LegacyCType
98        /// Simplified for lighter documentation, but the actual impls
99        /// range **from `1` up to `32`, plus a bunch of significant
100        /// lengths up to `1024`**.
101        unsafe // Safety: Rust arrays _are_ `#[repr(C)]`
102        impl<Item : CType> LegacyCType
103            for [Item; $N]
104        { __cfg_headers__! {
105            fn c_short_name_fmt (fmt: &'_ mut fmt::Formatter<'_>)
106              -> fmt::Result
107            {
108                // item_N_array
109                write!(fmt,
110                    concat!("{}_", stringify!($N), "_array"),
111                    Item::short_name(),
112                )
113            }
114
115            fn c_define_self (definer: &'_ mut dyn Definer)
116              -> io::Result<()>
117            {
118                let ref me = Self::c_var("").to_string();
119                definer.define_once(
120                    me,
121                    &mut |definer| {
122                        Item::define_self(&crate::headers::languages::C, definer)?;
123                        writeln!(definer.out(),
124                            concat!(
125                                "typedef struct {{\n",
126                                "    {inline_array};\n",
127                                "}} {me};\n",
128                            ),
129                            inline_array = Item::name_wrapping_var(&crate::headers::languages::C, concat!(
130                                "idx[", stringify!($N), "]",
131                            )),
132                            me = me,
133                        )
134                    }
135                )
136            }
137
138            fn c_var_fmt (
139                fmt: &'_ mut fmt::Formatter<'_>,
140                var_name: &'_ str,
141            ) -> fmt::Result
142            {
143                // _e.g._, item_N_array_t
144                write!(fmt,
145                    "{}_t{sep}{}",
146                    Self::c_short_name(),
147                    var_name,
148                    sep = if var_name.is_empty() { "" } else { " " },
149                )
150            }
151
152            __cfg_csharp__! {
153                fn csharp_define_self (definer: &'_ mut dyn Definer)
154                  -> io::Result<()>
155                {
156                    let ref me = Self::csharp_ty();
157                    Item::define_self(&crate::headers::languages::CSharp, definer)?;
158                    definer.define_once(me, &mut |definer| {
159                        let array_items = {
160                            // Poor man's specialization to use `fixed` arrays.
161                            if  [
162                                    "bool",
163                                    "u8", "u16", "u32", "u64", "usize",
164                                    "i8", "i16", "i32", "i64", "isize",
165                                    "float", "double",
166                                ].contains(&::core::any::type_name::<Item>())
167                            {
168                                format!(
169                                    "    public fixed {ItemTy} arr[{N}];\n",
170                                    ItemTy = Item::name(&crate::headers::languages::CSharp),
171                                    N = $N,
172                                    // no need for a marshaler here
173                                )
174                            } else {
175                                // Sadly for the general case fixed arrays are
176                                // not supported.
177                                (0 .. $N)
178                                    .map(|i| format!(
179                                        "    \
180                                        {marshaler}\
181                                        public {ItemTy} _{i};\n",
182                                        ItemTy = Item::name(&crate::headers::languages::CSharp),
183                                        i = i,
184                                        marshaler =
185                                            Item::csharp_marshaler()
186                                                .map(|m| format!("[MarshalAs({})]\n    ", m))
187                                                .as_deref()
188                                                .unwrap_or("")
189                                        ,
190                                    ))
191                                    .collect::<rust::String>()
192                            }
193                        };
194                        writeln!(definer.out(),
195                            concat!(
196                                "[StructLayout(LayoutKind.Sequential, Size = {size})]\n",
197                                "public unsafe struct {me} {{\n",
198                                "{array_items}",
199                                "}}\n",
200                            ),
201                            me = me,
202                            array_items = array_items,
203                            size = mem::size_of::<Self>(),
204                        )
205                    })
206                }
207            }
208        } type OPAQUE_KIND = OpaqueKind::Concrete; }
209
210        // ReprC
211        /// Simplified for lighter documentation, but the actual impls
212        /// range **from `1` up to `32`, plus a bunch of significant
213        /// lengths up to `1024`**.
214        unsafe
215        impl<Item : ReprC> ReprC
216            for [Item; $N]
217        {
218            type CLayout = [Item::CLayout; $N];
219
220            #[inline]
221            fn is_valid (it: &'_ Self::CLayout)
222              -> bool
223            {
224                it.iter().all(Item::is_valid)
225            }
226        }
227    )*);
228
229    (@fns
230        (
231            $(
232                $An:ident $(,
233                $Ai:ident)* $(,)?
234            )?
235        )
236    ) => (
237        // recurse
238        $(
239            impl_CTypes! {
240                @fns
241                ($($Ai ,)*)
242            }
243        )?
244
245        unsafe
246        impl<
247            Ret : ReprC, $(
248            $An : ReprC, $(
249            $Ai : ReprC,
250        )*)?> $crate::layout::__HasNiche__
251        for
252            unsafe extern "C" fn ($($An, $($Ai ,)*)?) -> Ret
253        {}
254
255        unsafe
256        impl<
257            Ret : ReprC, $(
258            $An : ReprC, $(
259            $Ai : ReprC,
260        )*)?> $crate::layout::__HasNiche__
261        for
262            /*unsafe*/ extern "C" fn ($($An, $($Ai ,)*)?) -> Ret
263        {}
264
265        // LegacyCType
266        /// Simplified for lighter documentation, but the actual impls include
267        /// **up to 9 function parameters**.
268        unsafe // Safety: this is the "blessed" type recommended across Rust
269               // literature. Still the alignment of function pointers is not
270               // as well-defined, as one would wish.
271        impl<
272            Ret : CType, $(
273            $An : CType, $(
274            $Ai : CType,
275        )*)?> LegacyCType
276            for Option<unsafe extern "C" fn ($($An, $($Ai ,)*)?) -> Ret>
277        { __cfg_headers__! {
278            fn c_short_name_fmt (fmt: &'_ mut fmt::Formatter<'_>)
279              -> fmt::Result
280            {
281                // ret_arg1_arg2_fptr
282                fmt.write_str(&Ret::short_name())?; $(
283                write!(fmt, "_{}", $An::short_name())?; $(
284                write!(fmt, "_{}", $Ai::short_name())?; )*)?
285                fmt.write_str("_fptr")
286            }
287
288            fn c_define_self (definer: &'_ mut dyn Definer)
289              -> io::Result<()>
290            {
291                Ret::define_self(&crate::headers::languages::C, definer)?; $(
292                $An::define_self(&crate::headers::languages::C, definer)?; $(
293                $Ai::define_self(&crate::headers::languages::C, definer)?; )*)?
294                Ok(())
295            }
296
297            fn c_var_fmt (
298                fmt: &'_ mut fmt::Formatter<'_>,
299                var_name: &'_ str,
300            ) -> fmt::Result
301            {
302                write!(fmt, "{} ", Ret::name(&crate::headers::languages::C))?;
303                write!(fmt, "(*{})(", var_name)?;
304                let _empty = true; $(
305                let _empty = false;
306                write!(fmt, "{}", $An::name(&crate::headers::languages::C))?; $(
307                write!(fmt, ", {}", $Ai::name(&crate::headers::languages::C))?; )*)?
308                if _empty {
309                    fmt.write_str("void")?;
310                }
311                fmt.write_str(")")
312            }
313
314            __cfg_csharp__! {
315                fn csharp_define_self (definer: &'_ mut dyn Definer)
316                  -> io::Result<()>
317                {
318                    Ret::define_self(&crate::headers::languages::CSharp, definer)?; $(
319                    $An::define_self(&crate::headers::languages::CSharp, definer)?; $(
320                    $Ai::define_self(&crate::headers::languages::CSharp, definer)?; )*)?
321                    let ref me = Self::name(&crate::headers::languages::CSharp).to_string();
322                    let ref mut _arg = {
323                        let mut iter = (0 ..).map(|c| format!("_{}", c));
324                        move || iter.next().unwrap()
325                    };
326                    definer.define_once(me, &mut |definer| writeln!(definer.out(),
327                        concat!(
328                            // IIUC,
329                            //   - For 32-bits / x86,
330                            //     Rust's extern "C" is the same as C#'s (default) Winapi:
331                            //     "cdecl" for Linux, and "stdcall" for Windows.
332                            //
333                            //   - For everything else, this is param is ignored.
334                            //     I guess because both OSes agree on the calling convention?
335                            "[UnmanagedFunctionPointer(CallingConvention.Winapi)]\n",
336
337                            "{ret_marshaler}public unsafe /* static */ delegate\n",
338                            "    {Ret}\n",
339                            "    {me} (", $("\n",
340                            "        {}{", stringify!($An), "}", $(",\n",
341                            "        {}{", stringify!($Ai), "}", )*)?
342                            ");\n"
343                        ),$(
344                        $An::csharp_marshaler()
345                            .map(|m| format!("[MarshalAs({})]\n        ", m))
346                            .as_deref()
347                            .unwrap_or("")
348                        , $(
349                        $Ai::csharp_marshaler()
350                            .map(|m| format!("[MarshalAs({})]\n        ", m))
351                            .as_deref()
352                            .unwrap_or("")
353                        , )*)?
354                        me = me,
355                        ret_marshaler =
356                            Ret::csharp_marshaler()
357                                .map(|m| format!("[return: MarshalAs({})]\n", m))
358                                .as_deref()
359                                .unwrap_or("")
360                        ,
361                        Ret = Ret::name(&crate::headers::languages::CSharp), $(
362                        $An = $An::name_wrapping_var(&crate::headers::languages::CSharp, &_arg()), $(
363                        $Ai = $Ai::name_wrapping_var(&crate::headers::languages::CSharp, &_arg()), )*)?
364                    ))
365                }
366
367                fn csharp_ty ()
368                  -> rust::String
369                {
370                    Self::c_short_name().to_string()
371                }
372
373                fn legacy_csharp_marshaler ()
374                  -> Option<rust::String>
375                {
376                    // This assumes the calling convention from the above
377                    // `UnmanagedFunctionPointer` attribute.
378                    Some("UnmanagedType.FunctionPtr".into())
379                }
380            }
381        } type OPAQUE_KIND = OpaqueKind::Concrete; }
382
383        /* == ReprC for Option-less == */
384
385        /// Simplified for lighter documentation, but the actual impls include
386        /// **up to 9 function parameters**.
387        unsafe // Safety: byte-wise the layout is the same, but the safety
388               // invariants will still have to be checked at each site.
389        impl<
390            Ret : ReprC, $(
391            $An : ReprC, $(
392            $Ai : ReprC,
393        )*)?> ReprC
394            for unsafe extern "C" fn ($($An, $($Ai ,)*)?) -> Ret
395        {
396            type CLayout = Option<
397                unsafe extern "C"
398                fn ($($An::CLayout, $($Ai::CLayout ,)*)?) -> Ret::CLayout
399            >;
400
401            #[inline]
402            fn is_valid (c_layout: &'_ Self::CLayout)
403              -> bool
404            {
405                c_layout.is_some()
406            }
407        }
408
409        /// Simplified for lighter documentation, but the actual impls include
410        /// **up to 9 function parameters**.
411        unsafe // Safety: byte-wise the layout is the same, but the safety
412               // invariants will still have to be checked at each site.
413        impl<
414            Ret : ReprC, $(
415            $An : ReprC, $(
416            $Ai : ReprC,
417        )*)?> ReprC
418            for /*unsafe*/ extern "C" fn ($($An, $($Ai ,)*)?) -> Ret
419        {
420            type CLayout = Option<
421                unsafe extern "C"
422                fn ($($An::CLayout, $($Ai::CLayout ,)*)?) -> Ret::CLayout
423            >;
424
425            #[inline]
426            fn is_valid (c_layout: &'_ Self::CLayout)
427              -> bool
428            {
429                c_layout.is_some()
430            }
431        }
432
433        // Improve the error message when encountering a non-`extern "C"` fn
434        // wrapped in an `Option` (otherwise `rustc` tunnelvisions _w.r.t_
435        // the lack of Niche).
436        unsafe // Safety: `Self : ReprC` is not met so this impl never happens
437        impl<
438            Ret : ReprC, $(
439            $An : ReprC, $(
440            $Ai : ReprC,
441        )*)?> crate::layout::__HasNiche__
442            for /*unsafe*/ /*extern "C"*/ fn ($($An, $($Ai ,)*)?) -> Ret
443        where
444            Self : ReprC, // bound not met
445        {
446            #[inline]
447            fn is_niche (_: &'_ Self::CLayout)
448              -> bool
449            {
450                unreachable!()
451            }
452        }
453        unsafe // Safety: `Self : ReprC` is not met so this impl never happens
454        impl<
455            Ret : ReprC, $(
456            $An : ReprC, $(
457            $Ai : ReprC,
458        )*)?> crate::layout::__HasNiche__
459            for unsafe /*extern "C"*/ fn ($($An, $($Ai ,)*)?) -> Ret
460        where
461            Self : ReprC, // bound not met
462        {
463            #[inline]
464            fn is_niche (_: &'_ Self::CLayout)
465            -> bool
466            {
467                unreachable!()
468            }
469        }
470    );
471
472    (@integers
473        $(
474            $unsafe:tt
475            $RustInt:ident => $CInt:literal $CSharpInt:literal,
476        )*
477    ) => ($(
478        $unsafe // Safety: guaranteed by the caller of the macro
479        impl LegacyCType
480            for $RustInt
481        { __cfg_headers__! {
482            fn c_short_name_fmt (fmt: &'_ mut fmt::Formatter<'_>)
483              -> fmt::Result
484            {
485                fmt.write_str($CInt)
486            }
487
488            fn c_define_self (definer: &'_ mut dyn Definer)
489              -> io::Result<()>
490            {
491                definer.define_once(
492                    "__int_headers__",
493                    &mut |definer| write!(definer.out(),
494                        concat!(
495                            "\n",
496                            "#include <stddef.h>\n",
497                            "#include <stdint.h>\n",
498                            "\n",
499                        ),
500                    ),
501                )
502            }
503
504            fn c_var_fmt (
505                fmt: &'_ mut fmt::Formatter<'_>,
506                var_name: &'_ str,
507            ) -> fmt::Result
508            {
509                write!(fmt,
510                    concat!($CInt, "_t{sep}{}"),
511                    var_name,
512                    sep = if var_name.is_empty() { "" } else { " " },
513                )
514            }
515
516            __cfg_csharp__! {
517                fn csharp_define_self (
518                    _: &'_ mut dyn crate::headers::Definer,
519                ) -> io::Result<()>
520                {
521                    Ok(())
522                }
523
524                fn csharp_ty ()
525                  -> rust::String
526                {
527                    $CSharpInt.into()
528                }
529            }
530        } type OPAQUE_KIND = OpaqueKind::Concrete; }
531        from_CType_impl_ReprC! { $RustInt }
532    )*);
533
534    (@floats
535        $(
536            $unsafe:tt
537            $fN:ident => $Cty:literal,
538        )*
539    ) => ($(
540        $unsafe // Safety: guaranteed by the caller of the macro
541        impl LegacyCType
542            for $fN
543        { __cfg_headers__! {
544            fn c_short_name_fmt (fmt: &'_ mut fmt::Formatter<'_>)
545              -> fmt::Result
546            {
547                fmt.write_str($Cty)
548            }
549
550            fn c_var_fmt (
551                fmt: &'_ mut fmt::Formatter<'_>,
552                var_name: &'_ str,
553            ) -> fmt::Result
554            {
555                write!(fmt,
556                    concat!($Cty, "{sep}{}"),
557                    var_name,
558                    sep = if var_name.is_empty() { "" } else { " " },
559                )
560            }
561
562            fn c_define_self (
563                _: &'_ mut dyn crate::headers::Definer,
564            ) -> io::Result<()>
565            {
566                Ok(())
567            }
568
569            __cfg_csharp__! {
570                fn csharp_define_self (
571                    _: &'_ mut dyn crate::headers::Definer,
572                ) -> io::Result<()>
573                {
574                    Ok(())
575                }
576
577                fn csharp_ty ()
578                  -> rust::String
579                {
580                    $Cty.into()
581                }
582            }
583        } type OPAQUE_KIND = OpaqueKind::Concrete; }
584        from_CType_impl_ReprC! { $fN }
585    )*);
586
587    (
588        @pointers
589    ) => (
590        unsafe
591        impl<T : CType> LegacyCType
592            for *const T
593        { __cfg_headers__! {
594            fn c_short_name_fmt (fmt: &'_ mut fmt::Formatter<'_>)
595              -> fmt::Result
596            {
597                write!(fmt, "{}_const_ptr", T::short_name())
598            }
599
600            fn c_define_self (definer: &'_ mut dyn Definer)
601              -> io::Result<()>
602            {
603                T::define_self(&crate::headers::languages::C, definer)
604            }
605
606            fn c_var_fmt (
607                fmt: &'_ mut fmt::Formatter<'_>,
608                var_name: &'_ str,
609            ) -> fmt::Result
610            {
611                write!(fmt,
612                    "{} const *{sep}{}",
613                    T::name(&crate::headers::languages::C),
614                    var_name,
615                    sep = if var_name.is_empty() { "" } else { " " },
616                )
617            }
618
619            __cfg_csharp__! {
620                fn csharp_define_self (definer: &'_ mut dyn $crate::headers::Definer)
621                  -> $crate::ඞ::io::Result<()>
622                {
623                    T::define_self(&crate::headers::languages::CSharp, definer)?;
624                    // definer.define_once("Const", &mut |definer| {
625                    //     definer.out().write_all(concat!(
626                    //         "[StructLayout(LayoutKind.Sequential)]\n",
627                    //         "public readonly struct Const<T> {\n",
628                    //         "    public readonly T value;\n",
629                    //         "}\n\n",
630                    //     ).as_bytes())
631                    // })?
632                    Ok(())
633                }
634
635                fn csharp_ty ()
636                  -> rust::String
637                {
638                    format!("{} /*const*/ *", T::name(&crate::headers::languages::CSharp))
639                }
640            }
641        } type OPAQUE_KIND = OpaqueKind::Concrete; }
642
643        unsafe
644        impl<T : ReprC> ReprC
645        for *const T
646        {
647            type CLayout = *const T::CLayout;
648
649            #[inline]
650            fn is_valid (_: &'_ Self::CLayout)
651              -> bool
652            {
653                true
654            }
655        }
656
657        unsafe
658        impl<T : CType> LegacyCType
659            for *mut T
660        { __cfg_headers__! {
661            fn c_short_name_fmt (fmt: &'_ mut fmt::Formatter<'_>)
662              -> fmt::Result
663            {
664                write!(fmt, "{}_ptr", T::short_name())
665            }
666
667            fn c_define_self (definer: &'_ mut dyn Definer)
668              -> io::Result<()>
669            {
670                T::define_self(&crate::headers::languages::C, definer)
671            }
672
673            fn c_var_fmt (
674                fmt: &'_ mut fmt::Formatter<'_>,
675                var_name: &'_ str,
676            ) -> fmt::Result
677            {
678                write!(fmt,
679                    "{} *{sep}{}",
680                    T::name(&crate::headers::languages::C),
681                    var_name,
682                    sep = if var_name.is_empty() { "" } else { " " },
683                )
684            }
685
686            __cfg_csharp__! {
687                fn csharp_define_self (definer: &'_ mut dyn $crate::headers::Definer)
688                  -> $crate::ඞ::io::Result<()>
689                {
690                    T::define_self(&crate::headers::languages::CSharp, definer)
691                }
692
693                fn csharp_ty ()
694                  -> rust::String
695                {
696                    format!("{} *", T::name(&crate::headers::languages::CSharp))
697                }
698            }
699        } type OPAQUE_KIND = OpaqueKind::Concrete; }
700        unsafe
701        impl<T : ReprC> ReprC
702            for *mut T
703        {
704            type CLayout = *mut T::CLayout;
705
706            #[inline]
707            fn is_valid (_: &'_ Self::CLayout)
708              -> bool
709            {
710                true
711            }
712        }
713    );
714
715    (
716        @zsts
717    ) => (
718        // needed for compatibility with functions returning `()`
719        // FIXME: Use special impls in `@fns` for `-> ()` instead.
720        unsafe
721        impl ReprC
722            for ()
723        {
724            type CLayout = CVoid;
725
726            #[inline]
727            fn is_valid (_: &'_ CVoid)
728              -> bool
729            {
730                panic!("It is a logic error to try and get a ZST from C");
731            }
732        }
733        // Needed for structs containing a `PhantomData` field.
734        unsafe
735        impl<T : ?Sized> ReprC
736            for PhantomData<T>
737        {
738            type CLayout = CVoid;
739
740            #[inline]
741            fn is_valid (_: &'_ CVoid)
742              -> bool
743            {
744                panic!("It is a logic error to try and get a ZST from C");
745            }
746        }
747    );
748} impl_CTypes! {} };
749
750macro_rules! impl_ReprC_for {(
751    $unsafe:tt {
752        $(
753            $(@for [$($generics:tt)+])? $T:ty
754                => |ref $it:tt : $Layout:ty| $expr:expr
755        ),* $(,)?
756    }
757) => (
758    $(
759        $unsafe
760        impl $(<$($generics)+>)? ReprC
761            for $T
762        {
763            type CLayout = $Layout;
764
765            #[inline]
766            fn is_valid (it: &'_ $Layout)
767              -> bool
768            {
769                let $it = it;
770                if $expr {
771                    true
772                } else {
773                    #[cfg(feature = "log")]
774                    ::log::error!(
775                        "{:#x?} is not a _valid_ bit pattern for the type `{}`",
776                        unsafe {
777                            ::core::slice::from_raw_parts(
778                                <*const _>::cast::<u8>(it),
779                                ::core::mem::size_of_val(it),
780                            )
781                        },
782                        ::core::any::type_name::<Self>(),
783                    );
784                    false
785                }
786            }
787        }
788    )*
789)}
790
791#[repr(transparent)]
792#[derive(Clone, Copy, PartialEq, Eq)]
793#[allow(missing_debug_implementations)]
794pub
795struct Bool(u8);
796
797#[cfg(feature = "js")]
798const _: () = {
799    use crate::js::*;
800
801    impl ReprNapi for Bool {
802        type NapiValue = JsBoolean;
803
804        fn to_napi_value (
805            self: Self,
806            env: &'_ Env,
807        ) -> Result< JsBoolean >
808        {
809            env.get_boolean(match self.0 {
810                0 => false,
811                1 => true,
812                bad => unreachable!("({:#x}: Bool) != 0x0, 0x1", bad),
813            })
814        }
815
816        fn from_napi_value (
817            _env: &'_ Env,
818            napi_value: JsBoolean,
819        ) -> Result<Self>
820        {
821            napi_value.get_value().map(|b: bool| Self(b as _))
822        }
823    }
824};
825
826unsafe
827    impl LegacyCType
828        for Bool
829    {
830        __cfg_headers__! {
831            fn c_short_name_fmt (fmt: &'_ mut fmt::Formatter<'_>)
832              -> fmt::Result
833            {
834                fmt.write_str("bool")
835            }
836
837            fn c_define_self (definer: &'_ mut dyn Definer)
838              -> io::Result<()>
839            {
840                definer.define_once(
841                    "bool",
842                    &mut |definer| {
843                        definer.out().write_all(
844                            b"\n#include <stdbool.h>\n\n"
845                        )
846                    },
847                )
848            }
849
850            fn c_var_fmt (
851                fmt: &'_ mut fmt::Formatter<'_>,
852                var_name: &'_ str,
853            ) -> fmt::Result
854            {
855                write!(fmt,
856                    "bool{sep}{}",
857                    var_name,
858                    sep = if var_name.is_empty() { "" } else { " " },
859                )
860            }
861
862            __cfg_csharp__! {
863                fn csharp_define_self (
864                    _: &'_ mut dyn crate::headers::Definer,
865                ) -> io::Result<()>
866                {
867                    Ok(())
868                }
869
870                fn legacy_csharp_marshaler ()
871                  -> Option<rust::String>
872                {
873                    Some("UnmanagedType.U1".into())
874                }
875
876                fn csharp_ty ()
877                  -> rust::String
878                {
879                    "bool".into()
880                }
881            }
882        }
883
884        type OPAQUE_KIND = OpaqueKind::Concrete;
885    }
886from_CType_impl_ReprC! { Bool }
887
888/// A `ReprC` _standalone_ type with the same layout and ABI as
889/// [`::libc::c_int`][crate::libc::c_int].
890///
891/// By _standalone_, the idea is that this is defined as a (`transparent`) _newtype_ `struct`,
892/// rather than as a _`type` alias_, which is error-prone and yields less-portable headers (since
893/// the header generation will resolve the type alias and emit, for instance, `int32_t`, ⚠️).
894///
895/// By using this type, you guarantee that the C `int` type be used in the headers.
896#[repr(transparent)]
897#[derive(Clone, Copy, PartialEq, Eq)]
898pub
899struct c_int(pub crate::libc::c_int);
900
901impl ::core::fmt::Debug for c_int {
902    fn fmt (self: &'_ c_int, fmt: &'_ mut ::core::fmt::Formatter<'_>)
903      -> ::core::fmt::Result
904    {
905        ::core::fmt::Debug::fmt(&self.0, fmt)
906    }
907}
908
909unsafe
910    impl LegacyCType
911        for c_int
912    {
913        __cfg_headers__! {
914            fn c_short_name_fmt (fmt: &'_ mut fmt::Formatter<'_>)
915                -> fmt::Result
916            {
917                fmt.write_str("int")
918            }
919
920            fn c_var_fmt (
921                fmt: &'_ mut fmt::Formatter<'_>,
922                var_name: &'_ str,
923            ) -> fmt::Result
924            {
925                write!(fmt,
926                    "int{sep}{}",
927                    var_name,
928                    sep = if var_name.is_empty() { "" } else { " " },
929                )
930            }
931
932            fn c_define_self (
933                _: &'_ mut dyn crate::headers::Definer,
934            ) -> io::Result<()>
935            {
936                Ok(())
937            }
938
939            __cfg_csharp__! {
940                fn csharp_define_self (
941                    _: &'_ mut dyn crate::headers::Definer,
942                ) -> io::Result<()>
943                {
944                    Ok(())
945                }
946
947                fn csharp_ty ()
948                  -> rust::String
949                {
950                    "int".into()
951                }
952
953                fn legacy_csharp_marshaler ()
954                  -> Option<rust::String>
955                {
956                    Some("UnmanagedType.SysInt".into())
957                }
958            }
959        }
960
961        type OPAQUE_KIND = OpaqueKind::Concrete;
962    }
963
964impl_ReprC_for! { unsafe {
965    bool
966        => |ref byte: Bool| (byte.0 & !0b1) == 0
967    ,
968
969    @for[T : ReprC]
970    ptr::NonNull<T>
971        => |ref it: *mut T::CLayout| {
972            it.is_null().not() &&
973            (*it as usize) % ::core::mem::align_of::<T>() == 0
974        }
975    ,
976    @for[T : ReprC]
977    ptr::NonNullRef<T>
978        => |ref it: *const T::CLayout| {
979            it.is_null().not() &&
980            (*it as usize) % ::core::mem::align_of::<T>() == 0
981        }
982    ,
983    @for[T : ReprC]
984    ptr::NonNullMut<T>
985        => |ref it: *mut T::CLayout| {
986            it.is_null().not() &&
987            (*it as usize) % ::core::mem::align_of::<T>() == 0
988        }
989    ,
990    @for[T : ReprC]
991    ptr::NonNullOwned<T>
992        => |ref it: *mut T::CLayout| {
993            it.is_null().not() &&
994            (*it as usize) % ::core::mem::align_of::<T>() == 0
995        }
996    ,
997    @for['a, T : 'a + ReprC]
998    &'a T
999        => |ref it: *const T::CLayout| {
1000            it.is_null().not() &&
1001            (*it as usize) % ::core::mem::align_of::<T>() == 0
1002        }
1003    ,
1004    @for['a, T : 'a + ReprC]
1005    &'a mut T
1006        => |ref it: *mut T::CLayout| {
1007            it.is_null().not() &&
1008            (*it as usize) % ::core::mem::align_of::<T>() == 0
1009        }
1010    ,
1011}}
1012
1013/* `HasNiche` from `niche.rs` impls `ReprC` for `Option<ptr>` types. */
1014
1015impl_ReprC_for! { unsafe {
1016    @for['out, T : 'out + Sized + ReprC]
1017    Out<'out, T>
1018        => |ref it: *mut T::CLayout| {
1019            (*it as usize) % ::core::mem::align_of::<T>() == 0
1020        },
1021}}
1022
1023pub
1024type OpaqueLayout<T> = OpaqueLayout_<
1025    ::core::marker::PhantomData<T>,
1026>;
1027
1028#[derive(Debug, Clone, Copy)]
1029pub
1030struct OpaqueLayout_<Phantom> (
1031    Phantom,
1032);
1033
1034from_CType_impl_ReprC!(@for[T] OpaqueLayout<T>);
1035unsafe
1036impl<T> CType for OpaqueLayout<T> {
1037    type OPAQUE_KIND = OpaqueKind::Opaque;
1038
1039    __cfg_headers__! {
1040        fn short_name ()
1041          -> String
1042        {
1043            let mut it = String::from("Opaque");
1044            crate::ඞ::append_unqualified_name(&mut it, ::core::any::type_name::<T>());
1045            it
1046        }
1047
1048        fn define_self__impl (
1049            language: &'_ dyn HeaderLanguage,
1050            definer: &'_ mut dyn Definer,
1051        ) -> io::Result<()>
1052        {
1053            language.emit_opaque_type(
1054                definer,
1055                &[
1056                    &format!(
1057                        "The layout of `{}` is opaque/subject to changes.",
1058                        ::core::any::type_name::<T>(),
1059                    ),
1060                ],
1061                &PhantomData::<Self>,
1062            )
1063        }
1064    }
1065}
1066
1067#[derive(Debug)]
1068#[repr(transparent)]
1069pub
1070struct Opaque<T> {
1071    pub concrete: T,
1072}
1073
1074impl<T> ::core::ops::Deref for Opaque<T> {
1075    type Target = T;
1076
1077    fn deref (self: &'_ Opaque<T>)
1078      -> &'_ T
1079    {
1080        &self.concrete
1081    }
1082}
1083
1084impl<T> ::core::ops::DerefMut for Opaque<T> {
1085    fn deref_mut (self: &'_ mut Opaque<T>)
1086      -> &'_ mut T
1087    {
1088        &mut self.concrete
1089    }
1090}
1091
1092#[apply(cfg_alloc)]
1093impl<T> From<rust::Box<T>> for rust::Box<Opaque<T>> {
1094    fn from (b: rust::Box<T>)
1095      -> rust::Box<Opaque<T>>
1096    {
1097        unsafe {
1098            rust::Box::from_raw(rust::Box::into_raw(b).cast())
1099        }
1100    }
1101}
1102
1103#[apply(cfg_alloc)]
1104impl<T> From<rust::Box<T>> for crate::boxed::Box_<Opaque<T>> {
1105    fn from (b: rust::Box<T>)
1106      -> repr_c::Box<Opaque<T>>
1107    {
1108        rust::Box::<Opaque<T>>::from(b).into()
1109    }
1110}
1111
1112impl<'r, T> From<&'r T> for &'r Opaque<T> {
1113    fn from (r: &'r T)
1114      -> &'r Opaque<T>
1115    {
1116        unsafe {
1117            &* <*const _>::cast::<Opaque<T>>(r)
1118        }
1119    }
1120}
1121
1122impl<'r, T> From<&'r mut T> for &'r mut Opaque<T> {
1123    fn from (r: &'r mut T)
1124      -> &'r mut Opaque<T>
1125    {
1126        unsafe {
1127            &mut* <*mut _>::cast::<Opaque<T>>(r)
1128        }
1129    }
1130}
1131
1132unsafe
1133impl<T> ReprC for Opaque<T> {
1134    type CLayout = OpaqueLayout<T>;
1135
1136    fn is_valid (_: &'_ Self::CLayout)
1137      -> bool
1138    {
1139        unreachable! {"\
1140            wondering about the validity of an opaque type \
1141            makes no sense\
1142        "};
1143    }
1144}
1145
1146opaque_impls! {
1147    @for['c] ::core::task::Context<'c>,
1148    @for['r] &'r str,
1149    @for['r, T] &'r [T],
1150    @for['r, T] &'r mut [T],
1151    @for[T] ::core::cell::RefCell<T>,
1152}
1153
1154#[cfg(feature = "alloc")]
1155opaque_impls! {
1156    rust::String,
1157    @for[T] rust::Box<T>,
1158    @for[T] ::alloc::rc::Rc<T>,
1159    @for[T] rust::Vec<T>,
1160    @for[K, V] ::alloc::collections::BTreeMap<K, V>,
1161}
1162
1163#[cfg(feature = "std")]
1164opaque_impls! {
1165    @for[K, V] ::std::collections::HashMap<K, V>,
1166    @for[T] ::std::sync::Arc<T>,
1167    @for[T] ::std::sync::Mutex<T>,
1168    @for[T] ::std::sync::RwLock<T>,
1169}
1170
1171// where
1172macro_rules! opaque_impls {(
1173    $(
1174        $(@for[$($generics:tt)*])? $T:ty
1175    ),* $(,)?
1176) => (
1177    $(
1178        unsafe
1179        impl<$($($generics)*)?>
1180            ReprC
1181        for
1182            $T
1183        where
1184            // …
1185        {
1186            type CLayout = OpaqueLayout<$T>;
1187
1188            fn is_valid (_: &'_ Self::CLayout)
1189              -> bool
1190            {
1191                unreachable! {"\
1192                    wondering about the validity of an opaque type \
1193                    makes no sense\
1194                "};
1195            }
1196        }
1197    )*
1198)} use opaque_impls;