mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-17 01:13:11 +00:00
Add a copy of cfg_if to core's internal_macros.rs
core can't depend on external crates the way std can. Rather than revert usage of cfg_if, add a copy of it to core. This does not export our copy, even unstably; such a change could occur in a later commit.
This commit is contained in:
parent
f0c4da4998
commit
0f505c6377
@ -187,3 +187,96 @@ macro_rules! impl_fn_for_zst {
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
/// A macro for defining `#[cfg]` if-else statements.
|
||||
///
|
||||
/// `cfg_if` is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade
|
||||
/// of `#[cfg]` cases, emitting the implementation which matches first.
|
||||
///
|
||||
/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code without having to
|
||||
/// rewrite each clause multiple times.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// cfg_if! {
|
||||
/// if #[cfg(unix)] {
|
||||
/// fn foo() { /* unix specific functionality */ }
|
||||
/// } else if #[cfg(target_pointer_width = "32")] {
|
||||
/// fn foo() { /* non-unix, 32-bit functionality */ }
|
||||
/// } else {
|
||||
/// fn foo() { /* fallback implementation */ }
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
// This is a copy of `cfg_if!` from the `cfg_if` crate.
|
||||
// The recursive invocations should use $crate if this is ever exported.
|
||||
macro_rules! cfg_if {
|
||||
// match if/else chains with a final `else`
|
||||
(
|
||||
$(
|
||||
if #[cfg( $i_meta:meta )] { $( $i_tokens:tt )* }
|
||||
) else+
|
||||
else { $( $e_tokens:tt )* }
|
||||
) => {
|
||||
cfg_if! {
|
||||
@__items () ;
|
||||
$(
|
||||
(( $i_meta ) ( $( $i_tokens )* )) ,
|
||||
)+
|
||||
(() ( $( $e_tokens )* )) ,
|
||||
}
|
||||
};
|
||||
|
||||
// match if/else chains lacking a final `else`
|
||||
(
|
||||
if #[cfg( $i_meta:meta )] { $( $i_tokens:tt )* }
|
||||
$(
|
||||
else if #[cfg( $e_meta:meta )] { $( $e_tokens:tt )* }
|
||||
)*
|
||||
) => {
|
||||
cfg_if! {
|
||||
@__items () ;
|
||||
(( $i_meta ) ( $( $i_tokens )* )) ,
|
||||
$(
|
||||
(( $e_meta ) ( $( $e_tokens )* )) ,
|
||||
)*
|
||||
}
|
||||
};
|
||||
|
||||
// Internal and recursive macro to emit all the items
|
||||
//
|
||||
// Collects all the previous cfgs in a list at the beginning, so they can be
|
||||
// negated. After the semicolon is all the remaining items.
|
||||
(@__items ( $( $_:meta , )* ) ; ) => {};
|
||||
(
|
||||
@__items ( $( $no:meta , )* ) ;
|
||||
(( $( $yes:meta )? ) ( $( $tokens:tt )* )) ,
|
||||
$( $rest:tt , )*
|
||||
) => {
|
||||
// Emit all items within one block, applying an appropriate #[cfg]. The
|
||||
// #[cfg] will require all `$yes` matchers specified and must also negate
|
||||
// all previous matchers.
|
||||
#[cfg(all(
|
||||
$( $yes , )?
|
||||
not(any( $( $no ),* ))
|
||||
))]
|
||||
cfg_if! { @__identity $( $tokens )* }
|
||||
|
||||
// Recurse to emit all other items in `$rest`, and when we do so add all
|
||||
// our `$yes` matchers to the list of `$no` matchers as future emissions
|
||||
// will have to negate everything we just matched as well.
|
||||
cfg_if! {
|
||||
@__items ( $( $no , )* $( $yes , )? ) ;
|
||||
$( $rest , )*
|
||||
}
|
||||
};
|
||||
|
||||
// Internal macro to make __apply work out right for different match types,
|
||||
// because of how macros match/expand stuff.
|
||||
(@__identity $( $tokens:tt )* ) => {
|
||||
$( $tokens )*
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user