@@ -321,6 +321,95 @@ pub macro debug_assert_matches($($arg:tt)*) {
321321    } 
322322} 
323323
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+ 
324413/// Returns whether the given expression matches any of the given patterns. 
325414/// 
326415/// Like in a `match` expression, the pattern can be optionally followed by `if` 
0 commit comments