diff --git a/src/macros.rs b/src/macros.rs index 6b5f403fdfb11..a2c3a08806171 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -93,20 +93,38 @@ macro_rules! prelude { /// Implement `Clone` and `Copy` for a struct, as well as `Debug`, `Eq`, `Hash`, and /// `PartialEq` if the `extra_traits` feature is enabled. /// +/// By default, it will mark a struct as `non_exhaustive`. To opt out, use the attribute +/// `#[@not_non_exhaustive]` as the first attribute of the struct. +/// /// Use [`s_no_extra_traits`] for structs where the `extra_traits` feature does not /// make sense, and for unions. macro_rules! s { ($( + $(#[@$not_non_exhaustive:ident])* $(#[$attr:meta])* pub $t:ident $i:ident { $($field:tt)* } )*) => ($( - s!(it: $(#[$attr])* pub $t $i { $($field)* }); + s!(it: $(#[@$not_non_exhaustive])* $(#[$attr])* pub $t $i { $($field)* }); )*); (it: $(#[$attr:meta])* pub union $i:ident { $($field:tt)* }) => ( compile_error!("unions cannot derive extra traits, use s_no_extra_traits instead"); ); + (it: #[@not_non_exhaustive] $(#[$attr:meta])* pub struct $i:ident { $($field:tt)* }) => ( + __item! { + #[repr(C)] + #[cfg_attr( + feature = "extra_traits", + ::core::prelude::v1::derive(Debug, Eq, Hash, PartialEq) + )] + #[::core::prelude::v1::derive(::core::clone::Clone, ::core::marker::Copy)] + #[allow(deprecated)] + $(#[$attr])* + pub struct $i { $($field)* } + } + ); + (it: $(#[$attr:meta])* pub struct $i:ident { $($field:tt)* }) => ( __item! { #[repr(C)] @@ -116,6 +134,7 @@ macro_rules! s { )] #[::core::prelude::v1::derive(::core::clone::Clone, ::core::marker::Copy)] #[allow(deprecated)] + #[non_exhaustive] $(#[$attr])* pub struct $i { $($field)* } } @@ -125,6 +144,9 @@ macro_rules! s { /// Implement `Clone` and `Copy` for a tuple struct, as well as `Debug`, `Eq`, `Hash`, /// and `PartialEq` if the `extra_traits` feature is enabled. /// +/// By default, it will mark a struct as `non_exhaustive`. To opt out, use the attribute +/// `#[@not_non_exhaustive]` as the first attribute of the struct. +/// /// This is the same as [`s`] but works for tuple structs. macro_rules! s_paren { ($( @@ -149,10 +171,11 @@ macro_rules! s_paren { /// Most items will prefer to use [`s`]. macro_rules! s_no_extra_traits { ($( + $(#[@$not_non_exhaustive:ident])* $(#[$attr:meta])* pub $t:ident $i:ident { $($field:tt)* } )*) => ($( - s_no_extra_traits!(it: $(#[$attr])* pub $t $i { $($field)* }); + s_no_extra_traits!(it: $(#[@$not_non_exhaustive])* $(#[$attr])* pub $t $i { $($field)* }); )*); (it: $(#[$attr:meta])* pub union $i:ident { $($field:tt)* }) => ( @@ -171,11 +194,22 @@ macro_rules! s_no_extra_traits { } ); + (it: #[@not_non_exhaustive] $(#[$attr:meta])* pub struct $i:ident { $($field:tt)* }) => ( + __item! { + #[repr(C)] + #[::core::prelude::v1::derive(::core::clone::Clone, ::core::marker::Copy)] + #[cfg_attr(feature = "extra_traits", ::core::prelude::v1::derive(Debug))] + $(#[$attr])* + pub struct $i { $($field)* } + } + ); + (it: $(#[$attr:meta])* pub struct $i:ident { $($field:tt)* }) => ( __item! { #[repr(C)] #[::core::prelude::v1::derive(::core::clone::Clone, ::core::marker::Copy)] #[cfg_attr(feature = "extra_traits", ::core::prelude::v1::derive(Debug))] + #[non_exhaustive] $(#[$attr])* pub struct $i { $($field)* } } diff --git a/src/unix/linux_like/linux/mod.rs b/src/unix/linux_like/linux/mod.rs index cbea6c796379b..75ac7668aab61 100644 --- a/src/unix/linux_like/linux/mod.rs +++ b/src/unix/linux_like/linux/mod.rs @@ -798,7 +798,6 @@ s! { } // linux/openat2.h - #[non_exhaustive] pub struct open_how { pub flags: crate::__u64, pub mode: crate::__u64, @@ -1329,7 +1328,6 @@ s! { // linux/pidfd.h - #[non_exhaustive] pub struct pidfd_info { pub mask: crate::__u64, pub cgroupid: crate::__u64, diff --git a/src/unix/mod.rs b/src/unix/mod.rs index c9a8964eb1099..e0dc5968c338b 100644 --- a/src/unix/mod.rs +++ b/src/unix/mod.rs @@ -149,6 +149,7 @@ s! { pub h_addr_list: *mut *mut c_char, } + #[@not_non_exhaustive] pub struct iovec { pub iov_base: *mut c_void, pub iov_len: size_t,