Coverage Report

Created: 2026-10-28 07:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/libc-0.2.191/src/macros.rs
Line
Count
Source
1
/// A macro for defining #[cfg] if-else statements.
2
///
3
/// This is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade of
4
/// `#[cfg]` cases, emitting the implementation which matches first.
5
///
6
/// This allows you to conveniently provide a long list #[cfg]'d blocks of code without having to
7
/// rewrite each clause multiple times.
8
macro_rules! cfg_if {
9
    // match if/else chains with a final `else`
10
    ($(
11
        if #[cfg($($meta:meta),*)] { $($it:item)* }
12
    ) else * else {
13
        $($it2:item)*
14
    }) => {
15
        cfg_if! {
16
            @__items
17
            () ;
18
            $( ( ($($meta),*) ($($it)*) ), )*
19
            ( () ($($it2)*) ),
20
        }
21
    };
22
23
    // match if/else chains lacking a final `else`
24
    (
25
        if #[cfg($($i_met:meta),*)] { $($i_it:item)* }
26
        $(
27
            else if #[cfg($($e_met:meta),*)] { $($e_it:item)* }
28
        )*
29
    ) => {
30
        cfg_if! {
31
            @__items
32
            () ;
33
            ( ($($i_met),*) ($($i_it)*) ),
34
            $( ( ($($e_met),*) ($($e_it)*) ), )*
35
            ( () () ),
36
        }
37
    };
38
39
    // Internal and recursive macro to emit all the items
40
    //
41
    // Collects all the negated `cfg`s in a list at the beginning and after the
42
    // semicolon is all the remaining items
43
    (@__items ($($not:meta,)*) ; ) => {};
44
    (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ),
45
     $($rest:tt)*) => {
46
        // Emit all items within one block, applying an appropriate #[cfg]. The
47
        // #[cfg] will require all `$m` matchers specified and must also negate
48
        // all previous matchers.
49
        cfg_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* }
50
51
        // Recurse to emit all other items in `$rest`, and when we do so add all
52
        // our `$m` matchers to the list of `$not` matchers as future emissions
53
        // will have to negate everything we just matched as well.
54
        cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* }
55
    };
56
57
    // Internal macro to Apply a cfg attribute to a list of items
58
    (@__apply $m:meta, $($it:item)*) => {
59
        $(#[$m] $it)*
60
    };
61
}
62
63
/// Create an internal crate prelude with `core` reexports and common types.
64
macro_rules! prelude {
65
    () => {
66
        mod types;
67
68
        /// Frequently-used types that are available on all platforms
69
        ///
70
        /// We need to reexport the core types so this works with `rust-dep-of-std`.
71
        mod prelude {
72
            // Exports from `core`
73
            #[allow(unused_imports)]
74
            pub(crate) use core::clone::Clone;
75
            #[allow(unused_imports)]
76
            pub(crate) use core::cmp::{
77
                Eq,
78
                PartialEq,
79
            };
80
            #[allow(unused_imports)]
81
            pub(crate) use core::default::Default;
82
            #[allow(unused_imports)]
83
            pub(crate) use core::iter::Iterator;
84
            #[allow(unused_imports)]
85
            pub(crate) use core::marker::{
86
                Copy,
87
                Send,
88
                Sync,
89
            };
90
            #[allow(unused_imports)]
91
            pub(crate) use core::option::Option::{
92
                self,
93
                None,
94
                Some,
95
            };
96
            #[allow(unused_imports)]
97
            pub(crate) use core::prelude::v1::derive;
98
            #[allow(unused_imports)]
99
            pub(crate) use core::{
100
                assert,
101
                cfg,
102
                compile_error,
103
                debug_assert,
104
                fmt,
105
                hash,
106
                iter,
107
                mem,
108
                panic,
109
                ptr,
110
                unimplemented,
111
            };
112
113
            #[allow(unused_imports)]
114
            pub(crate) use fmt::Debug;
115
            #[allow(unused_imports)]
116
            pub(crate) use mem::{
117
                align_of,
118
                align_of_val,
119
                size_of,
120
                size_of_val,
121
            };
122
123
            #[allow(unused_imports)]
124
            #[cfg(any(target_os = "linux", target_os = "android", target_os = "l4re"))]
125
            pub(crate) use crate::types::u32_cast_ioctl;
126
            #[allow(unused_imports)]
127
            pub(crate) use crate::types::{
128
                cstr,
129
                replace_array_items,
130
                u16_cast_short,
131
                u32_cast_int,
132
                u32_cast_long,
133
                u8_slice_cast_char_slice,
134
                ulong_cast_int,
135
                ulong_cast_uint,
136
                CEnumRepr,
137
                Padding,
138
            };
139
            // Commonly used types defined in this crate
140
            #[allow(unused_imports)]
141
            pub(crate) use crate::{
142
                c_char,
143
                c_double,
144
                c_float,
145
                c_int,
146
                c_long,
147
                c_longlong,
148
                c_short,
149
                c_uchar,
150
                c_uint,
151
                c_ulong,
152
                c_ulonglong,
153
                c_ushort,
154
                c_void,
155
                intptr_t,
156
                size_t,
157
                ssize_t,
158
                uintptr_t,
159
            };
160
        }
161
    };
162
}
163
164
/// Implement `Clone`, `Copy`, and `Debug` for one or more structs, as well as `PartialEq`, `Eq`,
165
/// and `Hash` if the `extra_traits` feature is enabled.
166
///
167
/// Also mark the type with `repr(C)`.
168
///
169
/// Use [`s_no_extra_traits`] for structs where the `extra_traits` feature does not make sense, and
170
/// for unions.
171
macro_rules! s {
172
    ($(
173
        $(#[$attr:meta])*
174
        $pub:vis $t:ident $i:ident { $($field:tt)* }
175
    )*) => ($(
176
        s!(it: $(#[$attr])* $pub $t $i { $($field)* });
177
    )*);
178
179
    (it: $(#[$attr:meta])* $pub:vis union $i:ident { $($field:tt)* }) => (
180
        compile_error!("unions cannot derive extra traits, use s_no_extra_traits instead");
181
    );
182
183
    (it: $(#[$attr:meta])* $pub:vis struct $i:ident { $($field:tt)* }) => (
184
        #[repr(C)]
185
        #[::core::prelude::v1::derive(
186
            ::core::clone::Clone,
187
            ::core::marker::Copy,
188
            ::core::fmt::Debug,
189
        )]
190
        #[cfg_attr(
191
            feature = "extra_traits",
192
            ::core::prelude::v1::derive(
193
                ::core::cmp::PartialEq,
194
                ::core::cmp::Eq,
195
                ::core::hash::Hash,
196
            )
197
        )]
198
        #[allow(deprecated)]
199
        $(#[$attr])*
200
        $pub struct $i { $($field)* }
201
    );
202
}
203
204
/// Implement `Clone`, `Copy`, and `Debug` for a tuple struct, as well as `PartialEq`, `Eq`, and
205
/// `Hash` if the `extra_traits` feature is enabled.
206
///
207
/// Unlike `s!`, this does *not* mark the type with `repr(C)`. Users should provide their own
208
/// `repr` attribute via `$attr` as necessary.
209
macro_rules! s_paren {
210
    ($(
211
        $(#[$attr:meta])*
212
        $pub:vis struct $i:ident ( $($field:tt)* );
213
    )*) => ($(
214
        #[::core::prelude::v1::derive(
215
            ::core::clone::Clone,
216
            ::core::marker::Copy,
217
            ::core::fmt::Debug,
218
        )]
219
        #[cfg_attr(
220
            feature = "extra_traits",
221
            ::core::prelude::v1::derive(
222
                ::core::cmp::PartialEq,
223
                ::core::cmp::Eq,
224
                ::core::hash::Hash,
225
            )
226
        )]
227
        $(#[$attr])*
228
        $pub struct $i ( $($field)* );
229
    )*);
230
}
231
232
/// Implement `Clone`, `Copy`, and `Debug` for one or more structs/unions, but exclude `PartialEq`,
233
/// `Eq`, and `Hash`.
234
///
235
/// Also mark the type with `repr(C)`.
236
///
237
/// Most structs will prefer to use [`s`].
238
macro_rules! s_no_extra_traits {
239
    ($(
240
        $(#$attr:tt)*
241
        $pub:vis $t:ident $i:ident { $($field:tt)* }
242
    )*) => ($(
243
        s_no_extra_traits!(it: $(#$attr)* $pub $t $i { $($field)* });
244
    )*);
245
246
    (it: $(#$attr:tt)* $pub:vis union $i:ident { $($field:tt)* }) => (
247
        union_with_debug! {
248
            $(#$attr)* $pub union $i { $($field)* }
249
        }
250
    );
251
252
    (it: $(#$attr:tt)* $pub:vis struct $i:ident { $($field:tt)* }) => (
253
        #[repr(C)]
254
        #[::core::prelude::v1::derive(
255
            ::core::clone::Clone,
256
            ::core::marker::Copy,
257
            ::core::fmt::Debug,
258
        )]
259
        $(#$attr)*
260
        $pub struct $i { $($field)* }
261
    );
262
}
263
264
/// Like [`s`], but (1) generates a `Default` impl for every struct in the block, and (2) adds a
265
/// private field to the struct to replicate the effects of the `non_exhaustive` attribute while
266
/// rust-lang/rust#132699 gets sorted out.
267
///
268
/// To opt out of having the private field added, annotate the struct with an `exhaustive`
269
/// attribute, as in:
270
///
271
/// ```ignore
272
/// s2! {
273
///     #[exhaustive]
274
///     struct Something {
275
///         ...
276
///     }
277
/// }
278
/// ```
279
///
280
/// See [`custom_struct`] for details.
281
macro_rules! s2 {
282
    ($(
283
        $(#$attr:tt)*
284
        $pub:vis $t:ident $i:ident { $($field:tt)* }
285
    )*) => ($(
286
        s2!(it: $(#$attr)* $pub $t $i { $($field)* });
287
    )*);
288
289
    (it: $(#$attr:tt)* $pub:vis union $i:ident { $($field:tt)* }) => (
290
        compile_error!(
291
            "unions cannot derive extra traits, use `s_no_extra_traits2` \
292
             instead"
293
        );
294
    );
295
296
    (it: $(#$attr:tt)* $pub:vis struct $i:ident { $($field:tt)* }) => (
297
        custom_struct! {
298
            attrs: {
299
                #[repr(C)]
300
                #[::core::prelude::v1::derive(
301
                    ::core::clone::Clone,
302
                    ::core::marker::Copy,
303
                    ::core::fmt::Debug,
304
                )]
305
                #[cfg_attr(
306
                    feature = "extra_traits",
307
                    ::core::prelude::v1::derive(
308
                        ::core::cmp::PartialEq,
309
                        ::core::cmp::Eq,
310
                        ::core::hash::Hash,
311
                    )
312
                )]
313
                #[allow(deprecated)]
314
            }
315
            $(#$attr)* $pub struct $i { $($field)* }
316
        }
317
    );
318
}
319
320
/// Like [`s_no_extra_traits`], but (1) generates a `Default` impl for every struct in the block,
321
/// and (2) adds a private field to replicate the effects of the built-in `non_exhaustive` attribute
322
/// while rust-lang/rust#132699 gets sorted out.
323
///
324
/// Unions are emitted just like `s_no_extra_traits!` does, with no `Default`.  A struct field of
325
/// union type supplies its own default via `#[custom_default(...)]`.
326
///
327
/// To opt out of having the private field added, annotate the struct with an `exhaustive`
328
/// attribute, as in:
329
///
330
/// ```ignore
331
/// s_no_extra_traits2! {
332
///     #[exhaustive]
333
///     struct Something {
334
///         ...
335
///     }
336
/// }
337
/// ```
338
macro_rules! s_no_extra_traits2 {
339
    ($(
340
        $(#$attr:tt)*
341
        $pub:vis $t:ident $i:ident { $($field:tt)* }
342
    )*) => ($(
343
        s_no_extra_traits2!(it: $(#$attr)* $pub $t $i { $($field)* });
344
    )*);
345
346
    (it: $(#$attr:tt)* $pub:vis union $i:ident { $($field:tt)* }) => (
347
        union_with_debug! {
348
            $(#$attr)* $pub union $i { $($field)* }
349
        }
350
    );
351
352
    (it: $(#$attr:tt)* $pub:vis struct $i:ident { $($field:tt)* }) => (
353
        custom_struct! {
354
            attrs: {
355
                #[repr(C)]
356
                #[::core::prelude::v1::derive(
357
                    ::core::clone::Clone,
358
                    ::core::marker::Copy,
359
                    ::core::fmt::Debug,
360
                )]
361
            }
362
            $(#$attr)* $pub struct $i { $($field)* }
363
        }
364
    );
365
}
366
367
/// Emit a union plus its `Debug` impl.
368
///
369
/// Unions can't derive `Debug`, so it is written out here. Attributes are split like
370
/// [`custom_struct`] does. Everything goes on the union, but only the `cfg`s are repeated on the
371
/// impl, otherwise a union that is configured out leaves an impl behind.
372
macro_rules! union_with_debug {
373
    (
374
        $(#$attr:tt)*
375
        $vis:vis union $name:ident { $($body:tt)* }
376
    ) => {
377
        union_with_debug! {
378
            @split_attrs,
379
            cfg_attrs: { },
380
            other_attrs: { },
381
            remaining_attrs: { $(#$attr)* },
382
            found_default_via_unsafe_zeroed: false,
383
            vis: $vis,
384
            name: $name,
385
            body: { $($body)* },
386
        }
387
    };
388
389
    // a `cfg` also has to gate the impl
390
    (
391
        @split_attrs,
392
        cfg_attrs: { $($cfg_attrs:tt)* },
393
        other_attrs: { $($other_attrs:tt)* },
394
        remaining_attrs: {
395
            #[cfg($($cfg:tt)*)]
396
            $($tail:tt)*
397
        },
398
        found_default_via_unsafe_zeroed: $found_default:tt,
399
        vis: $vis:vis,
400
        name: $name:ident,
401
        body: { $($body:tt)* },
402
    ) => {
403
        union_with_debug! {
404
            @split_attrs,
405
            cfg_attrs: { $($cfg_attrs)* #[cfg($($cfg)*)] },
406
            other_attrs: { $($other_attrs)* },
407
            remaining_attrs: { $($tail)* },
408
            found_default_via_unsafe_zeroed: $found_default,
409
            vis: $vis,
410
            name: $name,
411
            body: { $($body)* },
412
        }
413
    };
414
415
    // a `cfg` also has to gate the impl
416
    (
417
        @split_attrs,
418
        cfg_attrs: { $($cfg_attrs:tt)* },
419
        other_attrs: { $($other_attrs:tt)* },
420
        remaining_attrs: {
421
            #[unsafe(union_default_via_zeroed)]
422
            $($tail:tt)*
423
        },
424
        found_default_via_unsafe_zeroed: $found_default:tt,
425
        vis: $vis:vis,
426
        name: $name:ident,
427
        body: { $($body:tt)* },
428
    ) => {
429
        union_with_debug! {
430
            @split_attrs,
431
            cfg_attrs: { $($cfg_attrs)* },
432
            other_attrs: { $($other_attrs)* },
433
            remaining_attrs: { $($tail)* },
434
            found_default_via_unsafe_zeroed: true,
435
            vis: $vis,
436
            name: $name,
437
            body: { $($body)* },
438
        }
439
    };
440
441
    // anything else belongs to the union only
442
    (
443
        @split_attrs,
444
        cfg_attrs: { $($cfg_attrs:tt)* },
445
        other_attrs: { $($other_attrs:tt)* },
446
        remaining_attrs: {
447
            #$other:tt
448
            $($tail:tt)*
449
        },
450
        found_default_via_unsafe_zeroed: $found_default:tt,
451
        vis: $vis:vis,
452
        name: $name:ident,
453
        body: { $($body:tt)* },
454
    ) => {
455
        union_with_debug! {
456
            @split_attrs,
457
            cfg_attrs: { $($cfg_attrs)* },
458
            other_attrs: { $($other_attrs)* #$other },
459
            remaining_attrs: { $($tail)* },
460
            found_default_via_unsafe_zeroed: $found_default,
461
            vis: $vis,
462
            name: $name,
463
            body: { $($body)* },
464
        }
465
    };
466
467
    // done
468
    (
469
        @split_attrs,
470
        cfg_attrs: { $($cfg_attrs:tt)* },
471
        other_attrs: { $($other_attrs:tt)* },
472
        remaining_attrs: { },
473
        found_default_via_unsafe_zeroed: $found_default:tt,
474
        vis: $vis:vis,
475
        name: $name:ident,
476
        body: { $($body:tt)* },
477
    ) => {
478
        #[repr(C)]
479
        #[::core::prelude::v1::derive(
480
            ::core::clone::Clone,
481
            ::core::marker::Copy,
482
        )]
483
        $($other_attrs)*
484
        $($cfg_attrs)*
485
        $vis union $name { $($body)* }
486
487
        $($cfg_attrs)*
488
        #[allow(deprecated)]
489
        impl ::core::fmt::Debug for $name {
490
0
            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
491
0
                f.debug_struct(::core::stringify!($name)).finish_non_exhaustive()
492
0
            }
Unexecuted instantiation: <libc::unix::linux_like::linux_l4re_shared::__c_anonymous_ifr_ifru as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::unix::linux_like::linux::gnu::__c_anonymous_ptrace_syscall_info_data as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::unix::linux_like::linux_l4re_shared::__c_anonymous_ifc_ifcu as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::unix::linux_like::linux::iwreq_data as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::unix::linux_like::linux::__c_anonymous_iwreq as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::unix::linux_like::linux::__c_anonymous_ptp_perout_request_1 as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::unix::linux_like::linux::__c_anonymous_ptp_perout_request_2 as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::unix::linux_like::linux::__c_anonymous_xsk_tx_metadata_union as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::new::glibc::sysdeps::unix::linux::bits::types::siginfo_t::__c_anonymous_siginfo_t__si_fields as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::new::linux_uapi::linux::if_packet::tpacket_req_u as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::new::linux_uapi::linux::can::__c_anonymous_sockaddr_can_can_addr as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::new::glibc::sysdeps::unix::linux::bits::types::siginfo_t::__c_anonymous__sigfault__bounds as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::new::linux_uapi::linux::if_packet::tpacket_bd_header_u as core::fmt::Debug>::fmt
493
        }
494
495
        emit_union_default_via_unsafe_zeroed! {
496
            found_default_via_unsafe_zeroed: $found_default,
497
            cfg_attrs: { $($cfg_attrs)* },
498
            name: $name,
499
        }
500
    };
501
}
502
503
/// Add a `Default` impl that is just `mem::zeroed`.
504
macro_rules! emit_union_default_via_unsafe_zeroed {
505
    (
506
        found_default_via_unsafe_zeroed: false,
507
        cfg_attrs: { $($cfg_attrs:tt)* },
508
        name: $name:ident,
509
    ) => {
510
    };
511
512
    (
513
        found_default_via_unsafe_zeroed: true,
514
        cfg_attrs: { $($cfg_attrs:tt)* },
515
        name: $name:ident,
516
    ) => {
517
        $($cfg_attrs)*
518
        impl ::core::default::Default for $name {
519
            fn default() -> Self {
520
                unsafe { ::core::mem::zeroed() }
521
            }
522
        }
523
    };
524
}
525
526
/// Emit a struct with the given derive attributes plus a generated `Default` impl. Ensure that the
527
/// record has an additional private field added to replicate `#[non_exhaustive]`, unless it is
528
/// annotated with `#[exhaustive]`.
529
///
530
/// Fields default to `Default::default()`. A field whose default can't be derived must carry
531
/// `#[custom_default(EXPR)]` as its *first* attribute, and `EXPR` is used instead.
532
///
533
/// This works by scanning each field for `#[custom_default]` attributes. If one exists, the
534
/// attribute's contents are added to `processed_field_defaults` and will be used in the expansion
535
/// for `Default`. If it does not exist, `Default::default()` is used instead. In either case, the
536
/// field is added to `processed_fields` with `#[custom_default]` stripped if necessary, and
537
/// `custom_struct` is invoked again with the remaining fields.
538
///
539
/// Attributes are split into `cfg_attrs` and `other_attrs` before the fields are scanned. Both go
540
/// on the struct, but only the `cfg`s are repeated on the `Default` impl. A `cfg` decides whether
541
/// the type exists at all, so without it a configured-out struct leaves an impl behind referring to
542
/// a type that isn't there.
543
///
544
/// Out of `other_attrs`, we scan for `#[exhaustive]`. If found, we remove it but take into account
545
/// that the record should be expanded _without_ an additional private field. The scan for both
546
/// `cfg` attributes and the (non-existent) `exhaustive` attribute is done in one linear pass.
547
macro_rules! custom_struct {
548
    // entry; `attrs` is the attribute block the caller wants on the struct
549
    // (repr, derives, etc.), which is merged with the struct's own attributes.
550
    (
551
        attrs: { $($attrs:tt)* }
552
        $(#$attr:tt)*
553
        $vis:vis struct $name:ident { $($body:tt)* }
554
    ) => {
555
        custom_struct! {
556
            @split_attrs,
557
            cfg_attrs: { },
558
            other_attrs: { },
559
            remaining_attrs: { $($attrs)* $(#$attr)* },
560
            found_exhaustive_attr: false,
561
            vis: $vis,
562
            name: $name,
563
            body: { $($body)* },
564
        }
565
    };
566
567
    // a `cfg` also has to gate the impl
568
    (
569
        @split_attrs,
570
        cfg_attrs: { $($cfg_attrs:tt)* },
571
        other_attrs: { $($other_attrs:tt)* },
572
        remaining_attrs: {
573
            #[cfg($($cfg:tt)*)]
574
            $($tail:tt)*
575
        },
576
        found_exhaustive_attr: $found_exhaustive:tt,
577
        vis: $vis:vis,
578
        name: $name:ident,
579
        body: { $($body:tt)* },
580
    ) => {
581
        custom_struct! {
582
            @split_attrs,
583
            cfg_attrs: { $($cfg_attrs)* #[cfg($($cfg)*)] },
584
            other_attrs: { $($other_attrs)* },
585
            remaining_attrs: { $($tail)* },
586
            found_exhaustive_attr: $found_exhaustive,
587
            vis: $vis,
588
            name: $name,
589
            body: { $($body)* },
590
        }
591
    };
592
593
    // `exhaustive` must be taken into account as many times as it appears,
594
    // though the effect is the same with a single annotation.
595
    (
596
        @split_attrs,
597
        cfg_attrs: { $($cfg_attrs:tt)* },
598
        other_attrs: { $($other_attrs:tt)* },
599
        remaining_attrs: {
600
            #[exhaustive]
601
            $($tail:tt)*
602
        },
603
        found_exhaustive_attr: $_:tt,
604
        vis: $vis:vis,
605
        name: $name:ident,
606
        body: { $($body:tt)* },
607
    ) => {
608
        custom_struct! {
609
            @split_attrs,
610
            cfg_attrs: { $($cfg_attrs)* },
611
            other_attrs: { $($other_attrs)* },
612
            remaining_attrs: { $($tail)* },
613
            found_exhaustive_attr: true,
614
            vis: $vis,
615
            name: $name,
616
            body: { $($body)* },
617
        }
618
    };
619
620
    // anything else belongs to the struct only
621
    (
622
        @split_attrs,
623
        cfg_attrs: { $($cfg_attrs:tt)* },
624
        other_attrs: { $($other_attrs:tt)* },
625
        remaining_attrs: {
626
            #$other:tt
627
            $($tail:tt)*
628
        },
629
        found_exhaustive_attr: $found_exhaustive:tt,
630
        vis: $vis:vis,
631
        name: $name:ident,
632
        body: { $($body:tt)* },
633
    ) => {
634
        custom_struct! {
635
            @split_attrs,
636
            cfg_attrs: { $($cfg_attrs)* },
637
            other_attrs: { $($other_attrs)* #$other },
638
            remaining_attrs: { $($tail)* },
639
            found_exhaustive_attr: $found_exhaustive,
640
            vis: $vis,
641
            name: $name,
642
            body: { $($body)* },
643
        }
644
    };
645
646
    // attributes are split, move on to the fields
647
    (
648
        @split_attrs,
649
        cfg_attrs: { $($cfg_attrs:tt)* },
650
        other_attrs: { $($other_attrs:tt)* },
651
        remaining_attrs: { },
652
        found_exhaustive_attr: $found_exhaustive:tt,
653
        vis: $vis:vis,
654
        name: $name:ident,
655
        body: { $($body:tt)* },
656
    ) => {
657
        custom_struct! {
658
            @struct,
659
            cfg_attrs: { $($cfg_attrs)* },
660
            other_attrs: { $($other_attrs)* },
661
            found_exhaustive_attr: $found_exhaustive,
662
            vis: $vis,
663
            name: $name,
664
            processed_fields: { },
665
            processed_field_defaults: { },
666
            remaining_fields: { $($body)* },
667
        }
668
    };
669
670
    // field led by #[custom_default(...)]
671
    (
672
        @struct,
673
        cfg_attrs: { $($cfg_attrs:tt)* },
674
        other_attrs: { $($other_attrs:tt)* },
675
        found_exhaustive_attr: $found_exhaustive:tt,
676
        vis: $vis:vis,
677
        name: $name:ident,
678
        processed_fields: { $($processed_fields:tt)* },
679
        processed_field_defaults: { $($processed_field_defaults:tt)* },
680
        remaining_fields: {
681
            #[custom_default($default:expr)]
682
            $(#[$fattr:meta])*
683
            $fvis:vis $fname:ident: $fty:ty,
684
            $($tail:tt)*
685
        },
686
    ) => {
687
        custom_struct! {
688
            @struct,
689
            cfg_attrs: { $($cfg_attrs)* },
690
            other_attrs: { $($other_attrs)* },
691
            found_exhaustive_attr: $found_exhaustive,
692
            vis: $vis,
693
            name: $name,
694
            processed_fields: { $($processed_fields)* $(#[$fattr])* $fvis $fname: $fty, },
695
            processed_field_defaults: {
696
                $($processed_field_defaults)*
697
                $(#[$fattr])* $fname: $default,
698
            },
699
            remaining_fields: { $($tail)* },
700
        }
701
    };
702
703
    // plain field
704
    (
705
        @struct,
706
        cfg_attrs: { $($cfg_attrs:tt)* },
707
        other_attrs: { $($other_attrs:tt)* },
708
        found_exhaustive_attr: $found_exhaustive:tt,
709
        vis: $vis:vis,
710
        name: $name:ident,
711
        processed_fields: { $($processed_fields:tt)* },
712
        processed_field_defaults: { $($processed_field_defaults:tt)* },
713
        remaining_fields: {
714
            $(#[$fattr:meta])*
715
            $fvis:vis $fname:ident: $fty:ty,
716
            $($tail:tt)*
717
        },
718
    ) => {
719
        custom_struct! {
720
            @struct,
721
            cfg_attrs: { $($cfg_attrs)* },
722
            other_attrs: { $($other_attrs)* },
723
            found_exhaustive_attr: $found_exhaustive,
724
            vis: $vis,
725
            name: $name,
726
            processed_fields: { $($processed_fields)* $(#[$fattr])* $fvis $fname: $fty, },
727
            processed_field_defaults: {
728
                $($processed_field_defaults)*
729
                $(#[$fattr])* $fname: ::core::default::Default::default(),
730
            },
731
            remaining_fields: { $($tail)* },
732
        }
733
    };
734
735
    // done
736
    (
737
        @struct,
738
        cfg_attrs: { $($cfg_attrs:tt)* },
739
        other_attrs: { $($other_attrs:tt)* },
740
        found_exhaustive_attr: $found_exhaustive:tt,
741
        vis: $vis:vis,
742
        name: $name:ident,
743
        processed_fields: { $($processed_fields:tt)* },
744
        processed_field_defaults: { $($processed_field_defaults:tt)* },
745
        remaining_fields: { },
746
    ) => {
747
        emit_struct_definition! {
748
            found_exhaustive_attr: $found_exhaustive,
749
            body: {
750
                $($other_attrs)*
751
                $($cfg_attrs)*
752
                $vis $name { $($processed_fields)* }
753
            }
754
        }
755
756
        $($cfg_attrs)*
757
        // The impl names the type and its fields, which warns if either is
758
        // deprecated.
759
        #[allow(deprecated)]
760
        impl ::core::default::Default for $name {
761
            // Field attributes (`#[cfg]`, doc comments) get forwarded to the
762
            // initializer too. Docs are harmless there but trip the lint, so
763
            // silence it.
764
            #[allow(unused_doc_comments)]
765
0
            fn default() -> Self {
766
0
                emit_struct_default_body! {
767
                    found_exhaustive_attr: $found_exhaustive,
768
                    body: { $($processed_field_defaults)* }
769
                }
770
0
            }
Unexecuted instantiation: <libc::new::linux_uapi::linux::can::can_frame as core::default::Default>::default
Unexecuted instantiation: <libc::new::glibc::sysdeps::unix::linux::bits::statvfs::statvfs as core::default::Default>::default
Unexecuted instantiation: <libc::unix::protoent as core::default::Default>::default
Unexecuted instantiation: <libc::unix::in6_addr as core::default::Default>::default
Unexecuted instantiation: <libc::new::linux_uapi::linux::can::canfd_frame as core::default::Default>::default
Unexecuted instantiation: <libc::new::glibc::sysdeps::unix::linux::bits::statvfs::statvfs64 as core::default::Default>::default
Unexecuted instantiation: <libc::unix::group as core::default::Default>::default
Unexecuted instantiation: <libc::new::linux_uapi::linux::can::canxl_frame as core::default::Default>::default
Unexecuted instantiation: <libc::unix::utimbuf as core::default::Default>::default
Unexecuted instantiation: <libc::unix::winsize as core::default::Default>::default
Unexecuted instantiation: <libc::unix::linger as core::default::Default>::default
Unexecuted instantiation: <libc::unix::sigval as core::default::Default>::default
Unexecuted instantiation: <libc::unix::itimerval as core::default::Default>::default
Unexecuted instantiation: <libc::unix::tms as core::default::Default>::default
Unexecuted instantiation: <libc::unix::servent as core::default::Default>::default
Unexecuted instantiation: <libc::new::linux_uapi::linux::can::sockaddr_can as core::default::Default>::default
Unexecuted instantiation: <libc::unix::timeval as core::default::Default>::default
Unexecuted instantiation: <libc::unix::rlimit as core::default::Default>::default
Unexecuted instantiation: <libc::new::linux_uapi::linux::can::__c_anonymous_sockaddr_can_tp as core::default::Default>::default
Unexecuted instantiation: <libc::unix::rusage as core::default::Default>::default
Unexecuted instantiation: <libc::new::linux_uapi::linux::can::__c_anonymous_sockaddr_can_j1939 as core::default::Default>::default
Unexecuted instantiation: <libc::unix::ipv6_mreq as core::default::Default>::default
Unexecuted instantiation: <libc::new::linux_uapi::linux::can::can_filter as core::default::Default>::default
Unexecuted instantiation: <libc::unix::hostent as core::default::Default>::default
Unexecuted instantiation: <libc::unix::iovec as core::default::Default>::default
Unexecuted instantiation: <libc::unix::pollfd as core::default::Default>::default
771
        }
772
    };
773
}
774
775
/// Expands the definition of the record defined at [`custom_struct`], with either one of an
776
/// additional private field or with its verbatim fields.
777
macro_rules! emit_struct_definition {
778
    (
779
        found_exhaustive_attr: false,
780
        body: { $(#[$attr:meta])* $vis:vis $name:ident { $($field:tt)* } }
781
    ) => {
782
        #[allow(clippy::manual_non_exhaustive)]
783
        $(#[$attr])*
784
        $vis struct $name { $($field)* __non_exhaustive: () }
785
    };
786
787
    (
788
        found_exhaustive_attr: true,
789
        body: { $(#[$attr:meta])* $vis:vis $name:ident { $($field:tt)* } }
790
    ) => {
791
        $(#[$attr])*
792
        $vis struct $name { $($field)* }
793
    };
794
}
795
796
/// Expands the `Default` implementation of the record defined at [`custom_struct`], with either one
797
/// of an additional private field initialized to the unit value, or the record's fields verbatim.
798
macro_rules! emit_struct_default_body {
799
    (
800
        found_exhaustive_attr: false,
801
        body: { $($field_default:tt)* }
802
    ) => {
803
        Self { $($field_default)* __non_exhaustive: () }
804
    };
805
806
    (
807
        found_exhaustive_attr: true,
808
        body: { $($field_default:tt)* }
809
    ) => {
810
        Self { $($field_default)* }
811
    };
812
}
813
814
/// Create an uninhabited type that can't be constructed. It implements `Debug`, `Clone`, and
815
/// `Copy`, but these aren't meaningful for extern types so they should eventually be removed.
816
///
817
/// Really what we want here is something that also can't be named without indirection (in ADTs or
818
/// function signatures), but this doesn't exist.
819
macro_rules! extern_ty {
820
    ($(
821
        $(#[$attr:meta])*
822
        $vis:vis type $i:ident;
823
    )*) => ($(
824
        $(#[$attr])*
825
        /// This is an extern type ("opaque" or "incomplete" type in C).
826
        ///
827
        /// <div class="warning">
828
        /// This type's current representation allows inspecting some properties, such as via
829
        /// <code>size_of</code>, and it is technically possible to construct the type within
830
        /// <code>MaybeUninit</code>, However, this <strong>MUST NOT</strong> be relied upon
831
        /// because a future version of <code>libc</code> may switch to a proper
832
        /// <a href="https://rust-lang.github.io/rfcs/1861-extern-types.html">extern type</a>
833
        /// representation when available.
834
        /// </div>
835
        // ^ unfortunately warning blocks currently don't render markdown so we need to
836
        // use raw HTML.
837
        //
838
        // Representation based on the Nomicon:
839
        // <https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs>.
840
        //
841
        // FIXME(1.0): These traits are unreachable and should be removed.
842
        #[::core::prelude::v1::derive(
843
            ::core::clone::Clone,
844
            ::core::marker::Copy,
845
            ::core::fmt::Debug,
846
        )]
847
        #[repr(C)]
848
        $vis struct $i {
849
            _data: (),
850
            _marker: ::core::marker::PhantomData<(*mut u8, ::core::marker::PhantomPinned)>,
851
        }
852
    )*);
853
}
854
855
/// Implement `Clone` and `Copy` for an enum, as well as `Debug`, `Eq`, `Hash`, and
856
/// `PartialEq` if the `extra_traits` feature is enabled.
857
// FIXME(#4419): Replace all uses of `e!` with `c_enum!`
858
macro_rules! e {
859
    ($(
860
        $(#[$attr:meta])*
861
        pub enum $i:ident { $($field:tt)* }
862
    )*) => ($(
863
        #[cfg_attr(
864
            feature = "extra_traits",
865
            ::core::prelude::v1::derive(Eq, Hash, PartialEq)
866
        )]
867
        #[::core::prelude::v1::derive(
868
            ::core::clone::Clone,
869
            ::core::marker::Copy,
870
            ::core::fmt::Debug,
871
        )]
872
        $(#[$attr])*
873
        pub enum $i { $($field)* }
874
    )*);
875
}
876
877
/// Represent a C enum as Rust constants and a type.
878
///
879
/// C enums can't soundly be mapped to Rust enums since C enums are allowed to have duplicates or
880
/// unlisted values, but this is UB in Rust. This enum doesn't implement any traits, its main
881
/// purpose is to calculate the correct enum values.
882
///
883
/// Use the magic name `#anon` if the C enum doesn't create a type.
884
///
885
/// See <https://github.com/rust-lang/libc/issues/4419> for more.
886
macro_rules! c_enum {
887
    // Matcher for multiple enums
888
    ($(
889
        $(#[repr($repr:ty)])?
890
        $vis:vis enum $($ty_name:ident)? $(#$anon:ident)? {
891
            $(
892
                $(#[$meta:meta])*
893
                $field_vis:vis $variant:ident $(= $value:expr)?,
894
            )+
895
        }
896
    )+) => {
897
        $(c_enum!(@single;
898
            $(#[repr($repr)])?
899
            $vis enum $($ty_name)? $(#$anon)? {
900
                $(
901
                    $(#[$meta])*
902
                    $field_vis $variant $(= $value)?,
903
                )+
904
            }
905
        );)+
906
    };
907
908
    // Matcher for a single enum
909
    (@single;
910
        $(#[repr($repr:ty)])?
911
        $vis:vis enum $ty_name:ident {
912
            $(
913
                $(#[$meta:meta])*
914
                $field_vis:vis $variant:ident $(= $value:expr)?,
915
            )+
916
        }
917
    ) => {
918
        $vis type $ty_name = c_enum!(@ty $($repr)?);
919
        c_enum! {
920
            @variant;
921
            ty: $ty_name;
922
            default: 0;
923
            variants: [$(
924
                $(#[$meta])*
925
                $field_vis $variant $(= $value)?,
926
            )+]
927
        }
928
    };
929
930
    // Matcher for a single anonymous enum
931
    (@single;
932
        $(#[repr($repr:ty)])?
933
        $vis:vis enum #anon {
934
            $(
935
                $(#[$meta:meta])*
936
                $field_vis:vis $variant:ident $(= $value:expr)?,
937
            )+
938
        }
939
    ) => {
940
        c_enum! {
941
            @variant;
942
            ty: c_enum!(@ty $($repr)?);
943
            default: 0;
944
            variants: [$(
945
                $(#[$meta])*
946
                $field_vis $variant $(= $value)?,
947
            )+]
948
        }
949
    };
950
951
    // Matcher for variants: eats a single variant then recurses with the rest
952
    (@variant;
953
        ty: $_ty_name:ty;
954
        default: $_idx:expr;
955
        variants: []
956
    ) => { /* end of the chain */ };
957
    (
958
        @variant;
959
        ty: $ty_name:ty;
960
        default: $default_val:expr;
961
        variants: [
962
            $(#[$meta:meta])*
963
            $field_vis:vis $variant:ident $(= $value:expr)?,
964
            $($tail:tt)*
965
        ]
966
    ) => {
967
        $(#[$meta])*
968
        #[allow(deprecated)]
969
        $field_vis const $variant: $ty_name = {
970
            #[allow(unused_variables)]
971
            let r = $default_val;
972
            $(let r = $value;)?
973
            r
974
        };
975
976
        // The next value is always one more than the previous value, unless
977
        // set explicitly.
978
        c_enum! {
979
            @variant;
980
            ty: $ty_name;
981
            default: $variant + 1;
982
            variants: [$($tail)*]
983
        }
984
    };
985
986
    // Use a specific type if provided, otherwise default to `CEnumRepr`
987
    (@ty $repr:ty) => { $repr };
988
    (@ty) => { $crate::prelude::CEnumRepr };
989
}
990
991
/// Define a function that can be either `safe` or `unsafe` and optionally `const`. This always
992
/// marks the function inline and adds `extern "C"`.
993
macro_rules! f {
994
    ($(
995
        $(#[$attr:meta])*
996
        pub $(const $($const_dummy:literal)?)?
997
        $(unsafe $($unsafe_dummy:literal)?)? $(safe $($safe_dummy:literal)?)?
998
        fn $i:ident ($($arg:ident: $argty:ty),* $(,)?) -> $ret:ty
999
            $body:block
1000
    )+) => {$(
1001
        f! {
1002
            @single
1003
            $(#[$attr])*
1004
            pub $(const $($const_dummy)?)?
1005
            $(unsafe $($unsafe_dummy)?)? $(safe $($safe_dummy)?)?
1006
            fn $i ($($arg: $argty),*) -> $ret
1007
                $body
1008
        }
1009
    )+};
1010
1011
    (@single
1012
        $(#[$attr:meta])*
1013
        pub $(const $($const_dummy:literal)?)? unsafe
1014
        fn $i:ident ($($arg:ident: $argty:ty),* $(,)?) -> $ret:ty
1015
            $body:block
1016
    ) => {
1017
        #[inline]
1018
        $(#[$attr])*
1019
        pub $(const $($const_dummy)?)? unsafe extern "C"
1020
        fn $i ($($arg: $argty),*) -> $ret
1021
            $body
1022
    };
1023
1024
    (@single
1025
        $(#[$attr:meta])*
1026
        pub $(const $($const_dummy:literal)?)? safe
1027
        fn $i:ident ($($arg:ident: $argty:ty),* $(,)?) -> $ret:ty
1028
            $body:block
1029
    ) => {
1030
        #[inline]
1031
        $(#[$attr])*
1032
        pub $(const $($const_dummy)?)? extern "C"
1033
        fn $i ($($arg: $argty),*) -> $ret
1034
            $body
1035
    };
1036
1037
    (@single
1038
        pub $(const $($const_dummy:literal)?)?
1039
        fn $i:ident ($($arg:ident: $argty:ty),* $(,)?) -> $ret:ty
1040
            $body:block
1041
    ) => {
1042
        compile_error!("either `safe` or `unsafe` must be specified");
1043
    };
1044
}
1045
1046
// This macro is used to deprecate items that should be accessed via the mach2 crate
1047
macro_rules! deprecated_mach {
1048
    (pub const $id:ident: $ty:ty = $expr:expr;) => {
1049
        #[deprecated(
1050
            since = "0.2.55",
1051
            note = "Use the `mach2` crate instead",
1052
        )]
1053
        #[allow(deprecated)]
1054
        pub const $id: $ty = $expr;
1055
    };
1056
    ($(pub const $id:ident: $ty:ty = $expr:expr;)*) => {
1057
        $(
1058
            deprecated_mach!(
1059
                pub const $id: $ty = $expr;
1060
            );
1061
        )*
1062
    };
1063
    (pub type $id:ident = $ty:ty;) => {
1064
        #[deprecated(
1065
            since = "0.2.55",
1066
            note = "Use the `mach2` crate instead",
1067
        )]
1068
        #[allow(deprecated)]
1069
        pub type $id = $ty;
1070
    };
1071
    ($(pub type $id:ident = $ty:ty;)*) => {
1072
        $(
1073
            deprecated_mach!(
1074
                pub type $id = $ty;
1075
            );
1076
        )*
1077
    }
1078
}
1079
1080
/// Polyfill for std's `offset_of`.
1081
// FIXME(msrv): stabilized in std in 1.77
1082
macro_rules! offset_of {
1083
    ($Ty:path, $field:ident) => {{
1084
        // Taken from bytemuck, avoids accidentally calling on deref
1085
        #[allow(clippy::unneeded_wildcard_pattern)]
1086
        let $Ty { $field: _, .. };
1087
        let data = core::mem::MaybeUninit::<$Ty>::uninit();
1088
        let ptr = data.as_ptr();
1089
        // nested unsafe, see f!
1090
        #[allow(unused_unsafe)]
1091
        // SAFETY: computed address is inbounds since we have a stack alloc for
1092
        // T
1093
        let fptr = unsafe { core::ptr::addr_of!((*ptr).$field) };
1094
        let off = (fptr as usize).checked_sub(ptr as usize).unwrap();
1095
        core::assert!(off <= core::mem::size_of::<$Ty>());
1096
        off
1097
    }};
1098
}
1099
1100
#[cfg(test)]
1101
mod tests {
1102
    use core::any::TypeId;
1103
    use core::prelude::v1::*;
1104
1105
    use crate::types::CEnumRepr;
1106
1107
    #[test]
1108
    fn c_enum_basic() {
1109
        // By default, variants get sequential values.
1110
        c_enum! {
1111
            pub enum e {
1112
                VAR0,
1113
                VAR1,
1114
                VAR2,
1115
            }
1116
1117
            // Also check enums that don't create a type.
1118
            pub enum #anon {
1119
                ANON0,
1120
                ANON1,
1121
                ANON2,
1122
            }
1123
1124
            // No visibility required.
1125
            enum #anon {
1126
                ANON3,
1127
                ANON4,
1128
                ANON5,
1129
            }
1130
        }
1131
1132
        assert_eq!(TypeId::of::<e>(), TypeId::of::<CEnumRepr>());
1133
        assert_eq!(VAR0, 0 as CEnumRepr);
1134
        assert_eq!(VAR1, 1 as CEnumRepr);
1135
        assert_eq!(VAR2, 2 as CEnumRepr);
1136
1137
        assert_eq!(type_id_of_val(&ANON0), TypeId::of::<CEnumRepr>());
1138
        assert_eq!(ANON0, 0 as CEnumRepr);
1139
        assert_eq!(ANON1, 1 as CEnumRepr);
1140
        assert_eq!(ANON2, 2 as CEnumRepr);
1141
1142
        assert_eq!(type_id_of_val(&ANON3), TypeId::of::<CEnumRepr>());
1143
        assert_eq!(ANON3, 0 as CEnumRepr);
1144
        assert_eq!(ANON4, 1 as CEnumRepr);
1145
        assert_eq!(ANON5, 2 as CEnumRepr);
1146
    }
1147
1148
    #[test]
1149
    fn c_enum_repr() {
1150
        // Check specifying the integer representation
1151
        c_enum! {
1152
            #[repr(u16)]
1153
            pub enum e {
1154
                VAR0,
1155
            }
1156
1157
            #[repr(u16)]
1158
            pub enum #anon {
1159
                ANON0,
1160
            }
1161
        }
1162
1163
        assert_eq!(TypeId::of::<e>(), TypeId::of::<u16>());
1164
        assert_eq!(VAR0, 0_u16);
1165
1166
        assert_eq!(type_id_of_val(&ANON0), TypeId::of::<u16>());
1167
        assert_eq!(ANON0, 0_u16);
1168
    }
1169
1170
    #[test]
1171
    fn c_enum_set_value() {
1172
        // Setting an explicit value resets the count.
1173
        c_enum! {
1174
            pub enum e {
1175
                VAR2 = 2,
1176
                VAR3,
1177
                VAR4,
1178
            }
1179
        }
1180
1181
        assert_eq!(VAR2, 2 as CEnumRepr);
1182
        assert_eq!(VAR3, 3 as CEnumRepr);
1183
        assert_eq!(VAR4, 4 as CEnumRepr);
1184
    }
1185
1186
    #[test]
1187
    fn c_enum_multiple_set_value() {
1188
        // C enums always take one more than the previous value, unless set to a
1189
        // specific value. Duplicates are allowed.
1190
        c_enum! {
1191
            pub enum e {
1192
                VAR0,
1193
                VAR2_0 = 2,
1194
                VAR3_0,
1195
                VAR4_0,
1196
                VAR2_1 = 2,
1197
                VAR3_1,
1198
                VAR4_1,
1199
            }
1200
        }
1201
1202
        assert_eq!(VAR0, 0 as CEnumRepr);
1203
        assert_eq!(VAR2_0, 2 as CEnumRepr);
1204
        assert_eq!(VAR3_0, 3 as CEnumRepr);
1205
        assert_eq!(VAR4_0, 4 as CEnumRepr);
1206
        assert_eq!(VAR2_1, 2 as CEnumRepr);
1207
        assert_eq!(VAR3_1, 3 as CEnumRepr);
1208
        assert_eq!(VAR4_1, 4 as CEnumRepr);
1209
    }
1210
1211
    #[test]
1212
    fn c_enum_vis() {
1213
        mod priv1 {
1214
            c_enum! {
1215
                #[repr(u8)]
1216
                pub enum e1 {
1217
                    PRIV_ON_1 = 10,
1218
                    // Variant should still be usable within its visibility
1219
                    pub PUB1 = PRIV_ON_1 * 2,
1220
                }
1221
            }
1222
        }
1223
        mod priv2 {
1224
            c_enum! {
1225
                #[repr(u16)]
1226
                pub enum e2 {
1227
                    pub PRIV_ON_1 = 42,
1228
                    pub PUB2 = PRIV_ON_1 * 2,
1229
                }
1230
            }
1231
        }
1232
1233
        use priv1::*;
1234
        use priv2::*;
1235
1236
        assert_eq!(TypeId::of::<e1>(), TypeId::of::<u8>());
1237
        assert_eq!(TypeId::of::<e2>(), TypeId::of::<u16>());
1238
        assert_eq!(PUB1, 10u8 * 2);
1239
        assert_eq!(PUB2, 42u16 * 2);
1240
        // Verify that the default is private. If `PRIV_ON_1` was actually
1241
        // public in `priv1`, this would be an ambiguous import and/or type
1242
        // mismatch error.
1243
        assert_eq!(PRIV_ON_1, 42u16);
1244
    }
1245
1246
    #[test]
1247
    fn c_enum_attrs() {
1248
        // Note this can't work with `#[cfg]` currently because our expansion uses `previous + 1`
1249
        c_enum! {
1250
            pub enum e {
1251
                VAR0,
1252
                WITH_CFG = if cfg!(target_arch = "x86_64") { 86 } else { 1234 },
1253
                #[deprecated]
1254
                DEPRECATED,
1255
                NOT_DEPRECATED,
1256
            }
1257
        }
1258
1259
        if cfg!(target_arch = "x86_64") {
1260
            assert_eq!(WITH_CFG, 86);
1261
        } else {
1262
            assert_eq!(WITH_CFG, 1234);
1263
        }
1264
1265
        #[expect(deprecated)]
1266
        let _ = DEPRECATED;
1267
        #[deny(deprecated)]
1268
        let _ = NOT_DEPRECATED;
1269
    }
1270
1271
    #[test]
1272
    #[deny(unused_unsafe)]
1273
    fn f_safety() {
1274
        // Enusure the created functions are safe / unsafe / const as expected
1275
        f! {
1276
            pub unsafe fn unsafe_foo() -> u32 { 100 }
1277
            pub const unsafe fn const_unsafe_foo() -> u32 { 101 }
1278
            pub safe fn safe_foo() -> u32 { 200 }
1279
            pub const safe fn const_safe_foo() -> u32 { 201 }
1280
        }
1281
1282
        assert_eq!(unsafe { unsafe_foo() }, 100u32);
1283
        assert_eq!(const { unsafe { const_unsafe_foo() } }, 101u32);
1284
        assert_eq!(safe_foo(), 200u32);
1285
        assert_eq!(const { const_safe_foo() }, 201u32);
1286
1287
        // Check the ABI
1288
        let _: unsafe extern "C" fn() -> u32 = unsafe_foo;
1289
        let _: unsafe extern "C" fn() -> u32 = const_unsafe_foo;
1290
        let _: extern "C" fn() -> u32 = safe_foo;
1291
        let _: extern "C" fn() -> u32 = const_safe_foo;
1292
    }
1293
1294
    fn type_id_of_val<T: 'static>(_: &T) -> TypeId {
1295
        TypeId::of::<T>()
1296
    }
1297
1298
    #[test]
1299
    fn test_offset_of() {
1300
        #[repr(C)]
1301
        struct Off1 {
1302
            a: u8,
1303
            b: u32,
1304
            c: Off2,
1305
            d: u64,
1306
        }
1307
1308
        #[repr(C)]
1309
        #[repr(align(128))]
1310
        struct Off2 {}
1311
1312
        assert_eq!(core::mem::offset_of!(Off1, a), offset_of!(Off1, a));
1313
        assert_eq!(core::mem::offset_of!(Off1, b), offset_of!(Off1, b));
1314
        assert_eq!(core::mem::offset_of!(Off1, c), offset_of!(Off1, c));
1315
        assert_eq!(core::mem::offset_of!(Off1, d), offset_of!(Off1, d));
1316
    }
1317
1318
    #[test]
1319
    fn s2_is_non_exhaustive() {
1320
        // Without `#[exhaustive]`, the record should have an additional field
1321
        // added at the end. If this test compiles, it has it.
1322
        s2! {
1323
            struct Something {
1324
                a: u32,
1325
            }
1326
        }
1327
1328
        let s = Something::default();
1329
        assert_eq!(s.__non_exhaustive, ());
1330
    }
1331
1332
    #[test]
1333
    fn s2_uses_exhaustive() {
1334
        // With `#[exhaustive]`, the record should be regurgitated as-is. If
1335
        // this test compiles, then it works.
1336
        s2! {
1337
            #[exhaustive]
1338
            struct Something {
1339
                a: u32,
1340
            }
1341
        }
1342
1343
        #[allow(unused)]
1344
        let s = Something {
1345
            a: Default::default(),
1346
        };
1347
    }
1348
1349
    #[test]
1350
    fn s2_uses_mixed_exhaustive() {
1351
        // `#[exhaustive]` should work when sandwiched between attributes. If
1352
        // the test compiles, then it works.
1353
        s2! {
1354
            #[repr(align(8))]
1355
            #[exhaustive]
1356
            #[repr(align(2))]
1357
            struct Something {
1358
                a: u32,
1359
            }
1360
        }
1361
1362
        #[allow(unused)]
1363
        let s = Something {
1364
            a: Default::default(),
1365
        };
1366
    }
1367
1368
    #[test]
1369
    fn s2_uses_custom_default() {
1370
        // A non-default value proves `custom_default` is used rather than a
1371
        // derived default.
1372
        s2! {
1373
            struct CustomDefault {
1374
                a: u32,
1375
                #[custom_default([1; 64])]
1376
                buf: [u8; 64],
1377
            }
1378
        }
1379
1380
        let s = CustomDefault::default();
1381
        assert_eq!(s.a, 0);
1382
        assert_eq!(s.buf, [1u8; 64]);
1383
    }
1384
1385
    #[test]
1386
    fn s2_keeps_field_attrs() {
1387
        // If `custom_default` stripping ate the other field attributes, the two
1388
        // `a` fields would collide.
1389
        s2! {
1390
            struct FieldAttrs {
1391
                #[cfg(target_arch = "x86_64")]
1392
                a: u8,
1393
                #[cfg(not(target_arch = "x86_64"))]
1394
                a: u64,
1395
            }
1396
        }
1397
1398
        let s = FieldAttrs::default();
1399
        #[cfg(target_arch = "x86_64")]
1400
        assert_eq!(s.a, 0u8);
1401
        #[cfg(not(target_arch = "x86_64"))]
1402
        assert_eq!(s.a, 0u64);
1403
    }
1404
1405
    #[test]
1406
    fn s2_single_cfg_field() {
1407
        // This field only exists on x86_64, so its default init needs the same
1408
        // `cfg` or `Default` won't build on other arches.
1409
        s2! {
1410
            struct SingleCfg {
1411
                common: u32,
1412
                #[cfg(target_arch = "x86_64")]
1413
                x86_only: u64,
1414
            }
1415
        }
1416
1417
        let s = SingleCfg::default();
1418
        assert_eq!(s.common, 0);
1419
        #[cfg(target_arch = "x86_64")]
1420
        assert_eq!(s.x86_only, 0);
1421
    }
1422
1423
    #[test]
1424
    fn s_no_extra_traits2_zeroes_union() {
1425
        // A union field's default is supplied by
1426
        // `custom_default(unsafe { mem::zeroed })`.
1427
        s_no_extra_traits2! {
1428
            union U {
1429
                a: u32,
1430
                b: f32,
1431
            }
1432
1433
            struct HasUnion {
1434
                x: u16,
1435
                #[custom_default(unsafe { ::core::mem::zeroed::<U>() })]
1436
                u: U,
1437
            }
1438
        }
1439
1440
        let s = HasUnion::default();
1441
        assert_eq!(s.x, 0);
1442
        assert_eq!(unsafe { s.u.a }, 0);
1443
    }
1444
1445
    #[test]
1446
    fn s2_keeps_struct_cfg() {
1447
        // The opposite of the configured-out types in `macro_checks`. With the
1448
        // `cfg` true the type and its `Default` both exist, and the other
1449
        // attributes still apply.
1450
        s2! {
1451
            #[cfg(true)]
1452
            #[repr(align(8))]
1453
            /// a doc comment
1454
            struct EnabledCfg {
1455
                a: u32,
1456
                #[cfg(target_arch = "x86_64")]
1457
                x86_only: u8,
1458
                #[custom_default([1; 40])]
1459
                buf: [u8; 40],
1460
            }
1461
        }
1462
1463
        let s = EnabledCfg::default();
1464
        assert_eq!(s.a, 0);
1465
        assert_eq!(s.buf, [1u8; 40]);
1466
        assert_eq!(align_of::<EnabledCfg>(), 8);
1467
        #[cfg(target_arch = "x86_64")]
1468
        assert_eq!(s.x86_only, 0);
1469
    }
1470
1471
    #[test]
1472
    fn s2_union_default() {
1473
        s_no_extra_traits2! {
1474
            #[unsafe(union_default_via_zeroed)]
1475
            union Foo {
1476
                a: u32,
1477
                b: u64
1478
            }
1479
1480
            #[expect(unused)]
1481
            union Bar {
1482
                a: u32,
1483
                b: u64
1484
            }
1485
        }
1486
1487
        let f: Foo = Foo::default();
1488
        assert_eq!(unsafe { f.b }, 0);
1489
1490
        // Ensure it isn't always implemented, otherwise we would get a conflict.
1491
        impl Default for Bar {
1492
            fn default() -> Self {
1493
                unimplemented!()
1494
            }
1495
        }
1496
    }
1497
}
1498
1499
#[cfg(test)]
1500
#[allow(unused)]
1501
mod macro_checks {
1502
    use core::prelude::v1::*;
1503
1504
    s! {
1505
        pub struct S1 {
1506
            pub a: u32,
1507
            b: u32,
1508
        }
1509
1510
        struct S1Priv {
1511
            pub a: u32,
1512
            b: u32,
1513
        }
1514
    }
1515
1516
    s_no_extra_traits! {
1517
        pub struct S2 {
1518
            pub a: u32,
1519
            b: u32,
1520
        }
1521
1522
        struct S2Priv {
1523
            pub a: u32,
1524
            b: u32,
1525
        }
1526
1527
        pub union U2 {
1528
            pub a: u32,
1529
            b: f32,
1530
        }
1531
1532
        union U2Priv {
1533
            pub a: u32,
1534
            b: f32,
1535
        }
1536
    }
1537
1538
    extern_ty! {
1539
        type Foo;
1540
        pub type Bar;
1541
    }
1542
1543
    s2! {
1544
        pub struct S3 {
1545
            pub a: u32,
1546
            #[custom_default([1; 64])]
1547
            pub buf: [u8; 64],
1548
        }
1549
1550
        struct S3Priv {
1551
            pub a: u32,
1552
            b: u32,
1553
        }
1554
    }
1555
1556
    s_no_extra_traits2! {
1557
        pub union U3 {
1558
            pub a: u32,
1559
            b: f32,
1560
        }
1561
1562
        pub struct S4 {
1563
            pub a: u32,
1564
            #[custom_default(unsafe { ::core::mem::zeroed::<U3>() })]
1565
            pub u: U3,
1566
        }
1567
    }
1568
1569
    fn assert_impls_default<T: Default>() {}
1570
1571
    fn check_default() {
1572
        assert_impls_default::<S3>();
1573
        assert_impls_default::<S4>();
1574
    }
1575
1576
    // Types configured out entirely, checking that the generated impls carry
1577
    // the same `cfg` as the type. Without it they fail to compile with "cannot
1578
    // find type".
1579
    s2! {
1580
        #[cfg(false)]
1581
        pub struct S5 {
1582
            pub a: u32,
1583
            #[custom_default([1; 64])]
1584
            pub buf: [u8; 64],
1585
        }
1586
    }
1587
1588
    s_no_extra_traits! {
1589
        #[cfg(false)]
1590
        pub union U4 {
1591
            pub a: u32,
1592
            b: f32,
1593
        }
1594
    }
1595
1596
    s_no_extra_traits2! {
1597
        #[cfg(false)]
1598
        pub union U5 {
1599
            pub a: u32,
1600
            b: f32,
1601
        }
1602
1603
        #[cfg(false)]
1604
        pub struct S6 {
1605
            pub a: u32,
1606
        }
1607
    }
1608
1609
    // The generated impls name the type and its fields, so they need to allow
1610
    // deprecation.  `deny` turns the warning into an error if that ever stops
1611
    // being the case.
1612
    mod deprecated_checks {
1613
        #![deny(deprecated)]
1614
1615
        s2! {
1616
            #[deprecated(since = "0.0.0", note = "check that generated impls don't warn")]
1617
            pub struct S7 {
1618
                pub a: u32,
1619
            }
1620
        }
1621
1622
        s_no_extra_traits! {
1623
            #[deprecated(since = "0.0.0", note = "check that generated impls don't warn")]
1624
            pub union U6 {
1625
                pub a: u32,
1626
                b: f32,
1627
            }
1628
        }
1629
1630
        s_no_extra_traits2! {
1631
            #[deprecated(since = "0.0.0", note = "check that generated impls don't warn")]
1632
            pub union U7 {
1633
                pub a: u32,
1634
                b: f32,
1635
            }
1636
        }
1637
    }
1638
}