@@ -93,20 +93,38 @@ macro_rules! prelude {
9393/// Implement `Clone` and `Copy` for a struct, as well as `Debug`, `Eq`, `Hash`, and
9494/// `PartialEq` if the `extra_traits` feature is enabled.
9595///
96+ /// By default, it will mark a struct as `non_exhaustive`. To opt out, use the attribute
97+ /// `#[@not_non_exhaustive]` as the first attribute of the struct.
98+ ///
9699/// Use [`s_no_extra_traits`] for structs where the `extra_traits` feature does not
97100/// make sense, and for unions.
98101macro_rules! s {
99102 ( $(
103+ $( #[ @$not_non_exhaustive: ident] ) *
100104 $( #[ $attr: meta] ) *
101105 pub $t: ident $i: ident { $( $field: tt) * }
102106 ) * ) => ( $(
103- s!( it: $( #[ $attr] ) * pub $t $i { $( $field) * } ) ;
107+ s!( it: $( #[ @$not_non_exhaustive ] ) * $ ( # [ $attr] ) * pub $t $i { $( $field) * } ) ;
104108 ) * ) ;
105109
106110 ( it: $( #[ $attr: meta] ) * pub union $i: ident { $( $field: tt) * } ) => (
107111 compile_error!( "unions cannot derive extra traits, use s_no_extra_traits instead" ) ;
108112 ) ;
109113
114+ ( it: #[ @not_non_exhaustive] $( #[ $attr: meta] ) * pub struct $i: ident { $( $field: tt) * } ) => (
115+ __item! {
116+ #[ repr( C ) ]
117+ #[ cfg_attr(
118+ feature = "extra_traits" ,
119+ :: core:: prelude:: v1:: derive( Debug , Eq , Hash , PartialEq )
120+ ) ]
121+ #[ :: core:: prelude:: v1:: derive( :: core:: clone:: Clone , :: core:: marker:: Copy ) ]
122+ #[ allow( deprecated) ]
123+ $( #[ $attr] ) *
124+ pub struct $i { $( $field) * }
125+ }
126+ ) ;
127+
110128 ( it: $( #[ $attr: meta] ) * pub struct $i: ident { $( $field: tt) * } ) => (
111129 __item! {
112130 #[ repr( C ) ]
@@ -116,6 +134,7 @@ macro_rules! s {
116134 ) ]
117135 #[ :: core:: prelude:: v1:: derive( :: core:: clone:: Clone , :: core:: marker:: Copy ) ]
118136 #[ allow( deprecated) ]
137+ #[ non_exhaustive]
119138 $( #[ $attr] ) *
120139 pub struct $i { $( $field) * }
121140 }
@@ -125,6 +144,9 @@ macro_rules! s {
125144/// Implement `Clone` and `Copy` for a tuple struct, as well as `Debug`, `Eq`, `Hash`,
126145/// and `PartialEq` if the `extra_traits` feature is enabled.
127146///
147+ /// By default, it will mark a struct as `non_exhaustive`. To opt out, use the attribute
148+ /// `#[@not_non_exhaustive]` as the first attribute of the struct.
149+ ///
128150/// This is the same as [`s`] but works for tuple structs.
129151macro_rules! s_paren {
130152 ( $(
@@ -149,10 +171,11 @@ macro_rules! s_paren {
149171/// Most items will prefer to use [`s`].
150172macro_rules! s_no_extra_traits {
151173 ( $(
174+ $( #[ @$not_non_exhaustive: ident] ) *
152175 $( #[ $attr: meta] ) *
153176 pub $t: ident $i: ident { $( $field: tt) * }
154177 ) * ) => ( $(
155- s_no_extra_traits!( it: $( #[ $attr] ) * pub $t $i { $( $field) * } ) ;
178+ s_no_extra_traits!( it: $( #[ @$not_non_exhaustive ] ) * $ ( # [ $attr] ) * pub $t $i { $( $field) * } ) ;
156179 ) * ) ;
157180
158181 ( it: $( #[ $attr: meta] ) * pub union $i: ident { $( $field: tt) * } ) => (
@@ -171,11 +194,22 @@ macro_rules! s_no_extra_traits {
171194 }
172195 ) ;
173196
197+ ( it: #[ @not_non_exhaustive] $( #[ $attr: meta] ) * pub struct $i: ident { $( $field: tt) * } ) => (
198+ __item! {
199+ #[ repr( C ) ]
200+ #[ :: core:: prelude:: v1:: derive( :: core:: clone:: Clone , :: core:: marker:: Copy ) ]
201+ #[ cfg_attr( feature = "extra_traits" , :: core:: prelude:: v1:: derive( Debug ) ) ]
202+ $( #[ $attr] ) *
203+ pub struct $i { $( $field) * }
204+ }
205+ ) ;
206+
174207 ( it: $( #[ $attr: meta] ) * pub struct $i: ident { $( $field: tt) * } ) => (
175208 __item! {
176209 #[ repr( C ) ]
177210 #[ :: core:: prelude:: v1:: derive( :: core:: clone:: Clone , :: core:: marker:: Copy ) ]
178211 #[ cfg_attr( feature = "extra_traits" , :: core:: prelude:: v1:: derive( Debug ) ) ]
212+ #[ non_exhaustive]
179213 $( #[ $attr] ) *
180214 pub struct $i { $( $field) * }
181215 }
0 commit comments