@@ -168,6 +168,94 @@ pub macro assert_matches {
168
168
} ,
169
169
}
170
170
171
+ /// A macro for defining `#[cfg]` match-like statements.
172
+ ///
173
+ /// It is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade of
174
+ /// `#[ cfg] ` cases, emitting the implementation which matches first.
175
+ ///
176
+ /// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
177
+ /// without having to rewrite each clause multiple times.
178
+ ///
179
+ /// Trailing `_` wildcard match arms are **optional** and they indicate a fallback branch when
180
+ /// all previous declarations do not evaluate to true.
181
+ ///
182
+ /// # Example
183
+ ///
184
+ /// ```
185
+ /// #![feature(cfg_match)]
186
+ ///
187
+ /// cfg_match! {
188
+ /// cfg(unix) => {
189
+ /// fn foo() { /* unix specific functionality */ }
190
+ /// }
191
+ /// cfg(target_pointer_width = "32") => {
192
+ /// fn foo() { /* non-unix, 32-bit functionality */ }
193
+ /// }
194
+ /// _ => {
195
+ /// fn foo() { /* fallback implementation */ }
196
+ /// }
197
+ /// }
198
+ /// ```
199
+ #[ unstable ( feature = "cfg_match" , issue = "115585" ) ]
200
+ #[ rustc_diagnostic_item = "cfg_match" ]
201
+ pub macro cfg_match {
202
+ // with a final wildcard
203
+ (
204
+ $( cfg ( $initial_meta: meta) => { $( $initial_tokens: item) * } ) +
205
+ _ => { $( $extra_tokens: item) * }
206
+ ) => {
207
+ cfg_match ! {
208
+ @__items ( ) ;
209
+ $( ( ( $initial_meta) ( $( $initial_tokens) * ) ) , ) +
210
+ ( ( ) ( $( $extra_tokens) * ) ) ,
211
+ }
212
+ } ,
213
+
214
+ // without a final wildcard
215
+ (
216
+ $( cfg ( $extra_meta: meta) => { $( $extra_tokens: item) * } ) *
217
+ ) => {
218
+ cfg_match ! {
219
+ @__items ( ) ;
220
+ $( ( ( $extra_meta) ( $( $extra_tokens) * ) ) , ) *
221
+ }
222
+ } ,
223
+
224
+ // Internal and recursive macro to emit all the items
225
+ //
226
+ // Collects all the previous cfgs in a list at the beginning, so they can be
227
+ // negated. After the semicolon is all the remaining items.
228
+ ( @__items ( $( $_: meta, ) * ) ; ) => { } ,
229
+ (
230
+ @__items ( $( $no: meta, ) * ) ;
231
+ ( ( $( $yes: meta) ?) ( $( $tokens: item) * ) ) ,
232
+ $( $rest: tt, ) *
233
+ ) => {
234
+ // Emit all items within one block, applying an appropriate #[cfg]. The
235
+ // #[cfg] will require all `$yes` matchers specified and must also negate
236
+ // all previous matchers.
237
+ #[ cfg( all(
238
+ $( $yes, ) ?
239
+ not( any( $( $no) , * ) )
240
+ ) ) ]
241
+ cfg_match ! { @__identity $( $tokens) * }
242
+
243
+ // Recurse to emit all other items in `$rest`, and when we do so add all
244
+ // our `$yes` matchers to the list of `$no` matchers as future emissions
245
+ // will have to negate everything we just matched as well.
246
+ cfg_match ! {
247
+ @__items ( $( $no, ) * $( $yes, ) ?) ;
248
+ $( $rest, ) *
249
+ }
250
+ } ,
251
+
252
+ // Internal macro to make __apply work out right for different match types,
253
+ // because of how macros match/expand stuff.
254
+ ( @__identity $( $tokens: item) * ) => {
255
+ $( $tokens) *
256
+ }
257
+ }
258
+
171
259
/// Asserts that a boolean expression is `true` at runtime.
172
260
///
173
261
/// This will invoke the [`panic!`] macro if the provided expression cannot be
@@ -321,95 +409,6 @@ pub macro debug_assert_matches($($arg:tt)*) {
321
409
}
322
410
}
323
411
324
- /// A macro for defining `#[cfg]` match-like statements.
325
- ///
326
- /// It is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade of
327
- /// `#[cfg]` cases, emitting the implementation which matches first.
328
- ///
329
- /// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
330
- /// without having to rewrite each clause multiple times.
331
- ///
332
- /// Trailing `_` wildcard match arms are **optional** and they indicate a fallback branch when
333
- /// all previous declarations do not evaluate to true.
334
- ///
335
- /// # Example
336
- ///
337
- /// ```
338
- /// #![feature(cfg_match)]
339
- ///
340
- /// cfg_match! {
341
- /// cfg(unix) => {
342
- /// fn foo() { /* unix specific functionality */ }
343
- /// }
344
- /// cfg(target_pointer_width = "32") => {
345
- /// fn foo() { /* non-unix, 32-bit functionality */ }
346
- /// }
347
- /// _ => {
348
- /// fn foo() { /* fallback implementation */ }
349
- /// }
350
- /// }
351
- /// ```
352
- #[ macro_export]
353
- #[ unstable( feature = "cfg_match" , issue = "115585" ) ]
354
- #[ rustc_diagnostic_item = "cfg_match" ]
355
- macro_rules! cfg_match {
356
- // with a final wildcard
357
- (
358
- $( cfg( $initial_meta: meta) => { $( $initial_tokens: item) * } ) +
359
- _ => { $( $extra_tokens: item) * }
360
- ) => {
361
- cfg_match! {
362
- @__items ( ) ;
363
- $( ( ( $initial_meta) ( $( $initial_tokens) * ) ) , ) +
364
- ( ( ) ( $( $extra_tokens) * ) ) ,
365
- }
366
- } ;
367
-
368
- // without a final wildcard
369
- (
370
- $( cfg( $extra_meta: meta) => { $( $extra_tokens: item) * } ) *
371
- ) => {
372
- cfg_match! {
373
- @__items ( ) ;
374
- $( ( ( $extra_meta) ( $( $extra_tokens) * ) ) , ) *
375
- }
376
- } ;
377
-
378
- // Internal and recursive macro to emit all the items
379
- //
380
- // Collects all the previous cfgs in a list at the beginning, so they can be
381
- // negated. After the semicolon is all the remaining items.
382
- ( @__items ( $( $_: meta, ) * ) ; ) => { } ;
383
- (
384
- @__items ( $( $no: meta, ) * ) ;
385
- ( ( $( $yes: meta) ?) ( $( $tokens: item) * ) ) ,
386
- $( $rest: tt, ) *
387
- ) => {
388
- // Emit all items within one block, applying an appropriate #[cfg]. The
389
- // #[cfg] will require all `$yes` matchers specified and must also negate
390
- // all previous matchers.
391
- #[ cfg( all(
392
- $( $yes, ) ?
393
- not( any( $( $no) ,* ) )
394
- ) ) ]
395
- cfg_match! { @__identity $( $tokens) * }
396
-
397
- // Recurse to emit all other items in `$rest`, and when we do so add all
398
- // our `$yes` matchers to the list of `$no` matchers as future emissions
399
- // will have to negate everything we just matched as well.
400
- cfg_match! {
401
- @__items ( $( $no, ) * $( $yes, ) ?) ;
402
- $( $rest, ) *
403
- }
404
- } ;
405
-
406
- // Internal macro to make __apply work out right for different match types,
407
- // because of how macros match/expand stuff.
408
- ( @__identity $( $tokens: item) * ) => {
409
- $( $tokens) *
410
- } ;
411
- }
412
-
413
412
/// Returns whether the given expression matches any of the given patterns.
414
413
///
415
414
/// Like in a `match` expression, the pattern can be optionally followed by `if`
0 commit comments