@@ -101,20 +101,38 @@ macro_rules! prelude {
101101/// Implement `Clone` and `Copy` for a struct, as well as `Debug`, `Eq`, `Hash`, and
102102/// `PartialEq` if the `extra_traits` feature is enabled.
103103///
104+ /// By default, it will mark a struct as `non_exhaustive`. To opt out, use the attribute
105+ /// `#[@not_non_exhaustive]` as the first attribute of the struct.
106+ ///
104107/// Use [`s_no_extra_traits`] for structs where the `extra_traits` feature does not
105108/// make sense, and for unions.
106109macro_rules! s {
107110 ( $(
111+ $( #[ @$not_non_exhaustive: ident] ) *
108112 $( #[ $attr: meta] ) *
109113 pub $t: ident $i: ident { $( $field: tt) * }
110114 ) * ) => ( $(
111- s!( it: $( #[ $attr] ) * pub $t $i { $( $field) * } ) ;
115+ s!( it: $( #[ @$not_non_exhaustive ] ) * $ ( # [ $attr] ) * pub $t $i { $( $field) * } ) ;
112116 ) * ) ;
113117
114118 ( it: $( #[ $attr: meta] ) * pub union $i: ident { $( $field: tt) * } ) => (
115119 compile_error!( "unions cannot derive extra traits, use s_no_extra_traits instead" ) ;
116120 ) ;
117121
122+ ( it: #[ @not_non_exhaustive] $( #[ $attr: meta] ) * pub struct $i: ident { $( $field: tt) * } ) => (
123+ __item! {
124+ #[ repr( C ) ]
125+ #[ cfg_attr(
126+ feature = "extra_traits" ,
127+ :: core:: prelude:: v1:: derive( Debug , Eq , Hash , PartialEq )
128+ ) ]
129+ #[ :: core:: prelude:: v1:: derive( :: core:: clone:: Clone , :: core:: marker:: Copy ) ]
130+ #[ allow( deprecated) ]
131+ $( #[ $attr] ) *
132+ pub struct $i { $( $field) * }
133+ }
134+ ) ;
135+
118136 ( it: $( #[ $attr: meta] ) * pub struct $i: ident { $( $field: tt) * } ) => (
119137 __item! {
120138 #[ repr( C ) ]
@@ -124,6 +142,7 @@ macro_rules! s {
124142 ) ]
125143 #[ :: core:: prelude:: v1:: derive( :: core:: clone:: Clone , :: core:: marker:: Copy ) ]
126144 #[ allow( deprecated) ]
145+ #[ non_exhaustive]
127146 $( #[ $attr] ) *
128147 pub struct $i { $( $field) * }
129148 }
@@ -133,6 +152,9 @@ macro_rules! s {
133152/// Implement `Clone` and `Copy` for a tuple struct, as well as `Debug`, `Eq`, `Hash`,
134153/// and `PartialEq` if the `extra_traits` feature is enabled.
135154///
155+ /// By default, it will mark a struct as `non_exhaustive`. To opt out, use the attribute
156+ /// `#[@not_non_exhaustive]` as the first attribute of the struct.
157+ ///
136158/// This is the same as [`s`] but works for tuple structs.
137159macro_rules! s_paren {
138160 ( $(
@@ -157,10 +179,11 @@ macro_rules! s_paren {
157179/// Most items will prefer to use [`s`].
158180macro_rules! s_no_extra_traits {
159181 ( $(
182+ $( #[ @$not_non_exhaustive: ident] ) *
160183 $( #[ $attr: meta] ) *
161184 pub $t: ident $i: ident { $( $field: tt) * }
162185 ) * ) => ( $(
163- s_no_extra_traits!( it: $( #[ $attr] ) * pub $t $i { $( $field) * } ) ;
186+ s_no_extra_traits!( it: $( #[ @$not_non_exhaustive ] ) * $ ( # [ $attr] ) * pub $t $i { $( $field) * } ) ;
164187 ) * ) ;
165188
166189 ( it: $( #[ $attr: meta] ) * pub union $i: ident { $( $field: tt) * } ) => (
@@ -179,11 +202,22 @@ macro_rules! s_no_extra_traits {
179202 }
180203 ) ;
181204
205+ ( it: #[ @not_non_exhaustive] $( #[ $attr: meta] ) * pub struct $i: ident { $( $field: tt) * } ) => (
206+ __item! {
207+ #[ repr( C ) ]
208+ #[ :: core:: prelude:: v1:: derive( :: core:: clone:: Clone , :: core:: marker:: Copy ) ]
209+ #[ cfg_attr( feature = "extra_traits" , :: core:: prelude:: v1:: derive( Debug ) ) ]
210+ $( #[ $attr] ) *
211+ pub struct $i { $( $field) * }
212+ }
213+ ) ;
214+
182215 ( it: $( #[ $attr: meta] ) * pub struct $i: ident { $( $field: tt) * } ) => (
183216 __item! {
184217 #[ repr( C ) ]
185218 #[ :: core:: prelude:: v1:: derive( :: core:: clone:: Clone , :: core:: marker:: Copy ) ]
186219 #[ cfg_attr( feature = "extra_traits" , :: core:: prelude:: v1:: derive( Debug ) ) ]
220+ #[ non_exhaustive]
187221 $( #[ $attr] ) *
188222 pub struct $i { $( $field) * }
189223 }
0 commit comments