Adjust syntax
This commit is contained in:
parent
426d173423
commit
c89f0dc01d
7 changed files with 528 additions and 21 deletions
|
@ -4,6 +4,7 @@
|
|||
//! green/native threading. This is just a bare-bones enough solution for
|
||||
//! librustdoc, it is not production quality at all.
|
||||
|
||||
#[cfg(bootstrap)]
|
||||
cfg_match! {
|
||||
cfg(target_os = "linux") => {
|
||||
mod linux;
|
||||
|
@ -27,4 +28,28 @@ cfg_match! {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
cfg_match! {
|
||||
target_os = "linux" => {
|
||||
mod linux;
|
||||
use linux as imp;
|
||||
}
|
||||
target_os = "redox" => {
|
||||
mod linux;
|
||||
use linux as imp;
|
||||
}
|
||||
unix => {
|
||||
mod unix;
|
||||
use unix as imp;
|
||||
}
|
||||
windows => {
|
||||
mod windows;
|
||||
use self::windows as imp;
|
||||
}
|
||||
_ => {
|
||||
mod unsupported;
|
||||
use unsupported as imp;
|
||||
}
|
||||
}
|
||||
|
||||
pub use imp::Lock;
|
||||
|
|
|
@ -860,6 +860,7 @@ fn get_thread_id() -> u32 {
|
|||
}
|
||||
|
||||
// Memory reporting
|
||||
#[cfg(bootstrap)]
|
||||
cfg_match! {
|
||||
cfg(windows) => {
|
||||
pub fn get_resident_set_size() -> Option<usize> {
|
||||
|
@ -921,5 +922,67 @@ cfg_match! {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
cfg_match! {
|
||||
windows => {
|
||||
pub fn get_resident_set_size() -> Option<usize> {
|
||||
use std::mem;
|
||||
|
||||
use windows::{
|
||||
Win32::System::ProcessStatus::{K32GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS},
|
||||
Win32::System::Threading::GetCurrentProcess,
|
||||
};
|
||||
|
||||
let mut pmc = PROCESS_MEMORY_COUNTERS::default();
|
||||
let pmc_size = mem::size_of_val(&pmc);
|
||||
unsafe {
|
||||
K32GetProcessMemoryInfo(
|
||||
GetCurrentProcess(),
|
||||
&mut pmc,
|
||||
pmc_size as u32,
|
||||
)
|
||||
}
|
||||
.ok()
|
||||
.ok()?;
|
||||
|
||||
Some(pmc.WorkingSetSize)
|
||||
}
|
||||
}
|
||||
target_os = "macos" => {
|
||||
pub fn get_resident_set_size() -> Option<usize> {
|
||||
use libc::{c_int, c_void, getpid, proc_pidinfo, proc_taskinfo, PROC_PIDTASKINFO};
|
||||
use std::mem;
|
||||
const PROC_TASKINFO_SIZE: c_int = mem::size_of::<proc_taskinfo>() as c_int;
|
||||
|
||||
unsafe {
|
||||
let mut info: proc_taskinfo = mem::zeroed();
|
||||
let info_ptr = &mut info as *mut proc_taskinfo as *mut c_void;
|
||||
let pid = getpid() as c_int;
|
||||
let ret = proc_pidinfo(pid, PROC_PIDTASKINFO, 0, info_ptr, PROC_TASKINFO_SIZE);
|
||||
if ret == PROC_TASKINFO_SIZE {
|
||||
Some(info.pti_resident_size as usize)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
unix => {
|
||||
pub fn get_resident_set_size() -> Option<usize> {
|
||||
let field = 1;
|
||||
let contents = fs::read("/proc/self/statm").ok()?;
|
||||
let contents = String::from_utf8(contents).ok()?;
|
||||
let s = contents.split_whitespace().nth(field)?;
|
||||
let npages = s.parse::<usize>().ok()?;
|
||||
Some(npages * 4096)
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
pub fn get_resident_set_size() -> Option<usize> {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
|
|
@ -29,6 +29,7 @@ pub(crate) fn analyze_source_file(src: &str) -> (Vec<RelativeBytePos>, Vec<Multi
|
|||
(lines, multi_byte_chars)
|
||||
}
|
||||
|
||||
#[cfg(bootstrap)]
|
||||
cfg_match! {
|
||||
cfg(any(target_arch = "x86", target_arch = "x86_64")) => {
|
||||
fn analyze_source_file_dispatch(
|
||||
|
@ -185,6 +186,165 @@ cfg_match! {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
cfg_match! {
|
||||
any(target_arch = "x86", target_arch = "x86_64") => {
|
||||
fn analyze_source_file_dispatch(
|
||||
src: &str,
|
||||
lines: &mut Vec<RelativeBytePos>,
|
||||
multi_byte_chars: &mut Vec<MultiByteChar>,
|
||||
) {
|
||||
if is_x86_feature_detected!("sse2") {
|
||||
unsafe {
|
||||
analyze_source_file_sse2(src, lines, multi_byte_chars);
|
||||
}
|
||||
} else {
|
||||
analyze_source_file_generic(
|
||||
src,
|
||||
src.len(),
|
||||
RelativeBytePos::from_u32(0),
|
||||
lines,
|
||||
multi_byte_chars,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks 16 byte chunks of text at a time. If the chunk contains
|
||||
/// something other than printable ASCII characters and newlines, the
|
||||
/// function falls back to the generic implementation. Otherwise it uses
|
||||
/// SSE2 intrinsics to quickly find all newlines.
|
||||
#[target_feature(enable = "sse2")]
|
||||
unsafe fn analyze_source_file_sse2(
|
||||
src: &str,
|
||||
lines: &mut Vec<RelativeBytePos>,
|
||||
multi_byte_chars: &mut Vec<MultiByteChar>,
|
||||
) {
|
||||
#[cfg(target_arch = "x86")]
|
||||
use std::arch::x86::*;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use std::arch::x86_64::*;
|
||||
|
||||
const CHUNK_SIZE: usize = 16;
|
||||
|
||||
let src_bytes = src.as_bytes();
|
||||
|
||||
let chunk_count = src.len() / CHUNK_SIZE;
|
||||
|
||||
// This variable keeps track of where we should start decoding a
|
||||
// chunk. If a multi-byte character spans across chunk boundaries,
|
||||
// we need to skip that part in the next chunk because we already
|
||||
// handled it.
|
||||
let mut intra_chunk_offset = 0;
|
||||
|
||||
for chunk_index in 0..chunk_count {
|
||||
let ptr = src_bytes.as_ptr() as *const __m128i;
|
||||
// We don't know if the pointer is aligned to 16 bytes, so we
|
||||
// use `loadu`, which supports unaligned loading.
|
||||
let chunk = unsafe { _mm_loadu_si128(ptr.add(chunk_index)) };
|
||||
|
||||
// For character in the chunk, see if its byte value is < 0, which
|
||||
// indicates that it's part of a UTF-8 char.
|
||||
let multibyte_test = unsafe { _mm_cmplt_epi8(chunk, _mm_set1_epi8(0)) };
|
||||
// Create a bit mask from the comparison results.
|
||||
let multibyte_mask = unsafe { _mm_movemask_epi8(multibyte_test) };
|
||||
|
||||
// If the bit mask is all zero, we only have ASCII chars here:
|
||||
if multibyte_mask == 0 {
|
||||
assert!(intra_chunk_offset == 0);
|
||||
|
||||
// Check if there are any control characters in the chunk. All
|
||||
// control characters that we can encounter at this point have a
|
||||
// byte value less than 32 or ...
|
||||
let control_char_test0 = unsafe { _mm_cmplt_epi8(chunk, _mm_set1_epi8(32)) };
|
||||
let control_char_mask0 = unsafe { _mm_movemask_epi8(control_char_test0) };
|
||||
|
||||
// ... it's the ASCII 'DEL' character with a value of 127.
|
||||
let control_char_test1 = unsafe { _mm_cmpeq_epi8(chunk, _mm_set1_epi8(127)) };
|
||||
let control_char_mask1 = unsafe { _mm_movemask_epi8(control_char_test1) };
|
||||
|
||||
let control_char_mask = control_char_mask0 | control_char_mask1;
|
||||
|
||||
if control_char_mask != 0 {
|
||||
// Check for newlines in the chunk
|
||||
let newlines_test = unsafe { _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8)) };
|
||||
let newlines_mask = unsafe { _mm_movemask_epi8(newlines_test) };
|
||||
|
||||
if control_char_mask == newlines_mask {
|
||||
// All control characters are newlines, record them
|
||||
let mut newlines_mask = 0xFFFF0000 | newlines_mask as u32;
|
||||
let output_offset = RelativeBytePos::from_usize(chunk_index * CHUNK_SIZE + 1);
|
||||
|
||||
loop {
|
||||
let index = newlines_mask.trailing_zeros();
|
||||
|
||||
if index >= CHUNK_SIZE as u32 {
|
||||
// We have arrived at the end of the chunk.
|
||||
break;
|
||||
}
|
||||
|
||||
lines.push(RelativeBytePos(index) + output_offset);
|
||||
|
||||
// Clear the bit, so we can find the next one.
|
||||
newlines_mask &= (!1) << index;
|
||||
}
|
||||
|
||||
// We are done for this chunk. All control characters were
|
||||
// newlines and we took care of those.
|
||||
continue;
|
||||
} else {
|
||||
// Some of the control characters are not newlines,
|
||||
// fall through to the slow path below.
|
||||
}
|
||||
} else {
|
||||
// No control characters, nothing to record for this chunk
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// The slow path.
|
||||
// There are control chars in here, fallback to generic decoding.
|
||||
let scan_start = chunk_index * CHUNK_SIZE + intra_chunk_offset;
|
||||
intra_chunk_offset = analyze_source_file_generic(
|
||||
&src[scan_start..],
|
||||
CHUNK_SIZE - intra_chunk_offset,
|
||||
RelativeBytePos::from_usize(scan_start),
|
||||
lines,
|
||||
multi_byte_chars,
|
||||
);
|
||||
}
|
||||
|
||||
// There might still be a tail left to analyze
|
||||
let tail_start = chunk_count * CHUNK_SIZE + intra_chunk_offset;
|
||||
if tail_start < src.len() {
|
||||
analyze_source_file_generic(
|
||||
&src[tail_start..],
|
||||
src.len() - tail_start,
|
||||
RelativeBytePos::from_usize(tail_start),
|
||||
lines,
|
||||
multi_byte_chars,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// The target (or compiler version) does not support SSE2 ...
|
||||
fn analyze_source_file_dispatch(
|
||||
src: &str,
|
||||
lines: &mut Vec<RelativeBytePos>,
|
||||
multi_byte_chars: &mut Vec<MultiByteChar>,
|
||||
) {
|
||||
analyze_source_file_generic(
|
||||
src,
|
||||
src.len(),
|
||||
RelativeBytePos::from_u32(0),
|
||||
lines,
|
||||
multi_byte_chars,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// `scan_len` determines the number of bytes in `src` to scan. Note that the
|
||||
// function can read past `scan_len` if a multi-byte character start within the
|
||||
// range but extends past it. The overflow is returned by the function.
|
||||
|
|
|
@ -224,6 +224,7 @@ pub macro assert_matches {
|
|||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(bootstrap)]
|
||||
#[unstable(feature = "cfg_match", issue = "115585")]
|
||||
#[rustc_diagnostic_item = "cfg_match"]
|
||||
pub macro cfg_match {
|
||||
|
@ -284,6 +285,57 @@ pub macro cfg_match {
|
|||
}
|
||||
}
|
||||
|
||||
/// A macro for defining `#[cfg]` match-like statements.
|
||||
///
|
||||
/// It 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.
|
||||
///
|
||||
/// Trailing `_` wildcard match arms are **optional** and they indicate a fallback branch when
|
||||
/// all previous declarations do not evaluate to true.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(cfg_match)]
|
||||
///
|
||||
/// cfg_match! {
|
||||
/// unix => {
|
||||
/// fn foo() { /* unix specific functionality */ }
|
||||
/// }
|
||||
/// target_pointer_width = "32" => {
|
||||
/// fn foo() { /* non-unix, 32-bit functionality */ }
|
||||
/// }
|
||||
/// _ => {
|
||||
/// fn foo() { /* fallback implementation */ }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(not(bootstrap))]
|
||||
#[unstable(feature = "cfg_match", issue = "115585")]
|
||||
#[rustc_diagnostic_item = "cfg_match"]
|
||||
pub macro cfg_match {
|
||||
({ $($tt:tt)* }) => {{
|
||||
cfg_match! { $($tt)* }
|
||||
}},
|
||||
(_ => { $($output:tt)* }) => {
|
||||
$($output)*
|
||||
},
|
||||
(
|
||||
$cfg:meta => $output:tt
|
||||
$($( $rest:tt )+)?
|
||||
) => {
|
||||
#[cfg($cfg)]
|
||||
cfg_match! { _ => $output }
|
||||
$(
|
||||
#[cfg(not($cfg))]
|
||||
cfg_match! { $($rest)+ }
|
||||
)?
|
||||
},
|
||||
}
|
||||
|
||||
/// Asserts that a boolean expression is `true` at runtime.
|
||||
///
|
||||
/// This will invoke the [`panic!`] macro if the provided expression cannot be
|
||||
|
|
|
@ -149,7 +149,10 @@ mod intrinsics;
|
|||
mod io;
|
||||
mod iter;
|
||||
mod lazy;
|
||||
#[cfg(not(bootstrap))]
|
||||
mod macros;
|
||||
#[cfg(bootstrap)]
|
||||
mod macros_bootstrap;
|
||||
mod manually_drop;
|
||||
mod mem;
|
||||
mod net;
|
||||
|
|
|
@ -10,7 +10,7 @@ struct Struct;
|
|||
|
||||
impl Trait for Struct {
|
||||
cfg_match! {
|
||||
cfg(feature = "blah") => {
|
||||
feature = "blah" => {
|
||||
fn blah(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
@ -47,21 +47,21 @@ fn matches_leading_pipe() {
|
|||
#[test]
|
||||
fn cfg_match_basic() {
|
||||
cfg_match! {
|
||||
cfg(target_pointer_width = "64") => { fn f0_() -> bool { true }}
|
||||
target_pointer_width = "64" => { fn f0_() -> bool { true }}
|
||||
}
|
||||
|
||||
cfg_match! {
|
||||
cfg(unix) => { fn f1_() -> bool { true }}
|
||||
cfg(any(target_os = "macos", target_os = "linux")) => { fn f1_() -> bool { false }}
|
||||
unix => { fn f1_() -> bool { true } }
|
||||
any(target_os = "macos", target_os = "linux") => { fn f1_() -> bool { false }}
|
||||
}
|
||||
|
||||
cfg_match! {
|
||||
cfg(target_pointer_width = "32") => { fn f2_() -> bool { false }}
|
||||
cfg(target_pointer_width = "64") => { fn f2_() -> bool { true }}
|
||||
target_pointer_width = "32" => { fn f2_() -> bool { false } }
|
||||
target_pointer_width = "64" => { fn f2_() -> bool { true } }
|
||||
}
|
||||
|
||||
cfg_match! {
|
||||
cfg(target_pointer_width = "16") => { fn f3_() -> i32 { 1 }}
|
||||
target_pointer_width = "16" => { fn f3_() -> i32 { 1 } }
|
||||
_ => { fn f3_() -> i32 { 2 }}
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ fn cfg_match_basic() {
|
|||
#[test]
|
||||
fn cfg_match_debug_assertions() {
|
||||
cfg_match! {
|
||||
cfg(debug_assertions) => {
|
||||
debug_assertions => {
|
||||
assert!(cfg!(debug_assertions));
|
||||
assert_eq!(4, 2+2);
|
||||
}
|
||||
|
@ -98,13 +98,13 @@ fn cfg_match_debug_assertions() {
|
|||
#[test]
|
||||
fn cfg_match_no_duplication_on_64() {
|
||||
cfg_match! {
|
||||
cfg(windows) => {
|
||||
windows => {
|
||||
fn foo() {}
|
||||
}
|
||||
cfg(unix) => {
|
||||
unix => {
|
||||
fn foo() {}
|
||||
}
|
||||
cfg(target_pointer_width = "64") => {
|
||||
target_pointer_width = "64" => {
|
||||
fn foo() {}
|
||||
}
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ fn cfg_match_no_duplication_on_64() {
|
|||
#[test]
|
||||
fn cfg_match_options() {
|
||||
cfg_match! {
|
||||
cfg(test) => {
|
||||
test => {
|
||||
use core::option::Option as Option2;
|
||||
fn works1() -> Option2<u32> { Some(1) }
|
||||
}
|
||||
|
@ -122,26 +122,26 @@ fn cfg_match_options() {
|
|||
}
|
||||
|
||||
cfg_match! {
|
||||
cfg(feature = "foo") => { fn works2() -> bool { false } }
|
||||
cfg(test) => { fn works2() -> bool { true } }
|
||||
feature = "foo" => { fn works2() -> bool { false } }
|
||||
test => { fn works2() -> bool { true } }
|
||||
_ => { fn works2() -> bool { false } }
|
||||
}
|
||||
|
||||
cfg_match! {
|
||||
cfg(feature = "foo") => { fn works3() -> bool { false } }
|
||||
feature = "foo" => { fn works3() -> bool { false } }
|
||||
_ => { fn works3() -> bool { true } }
|
||||
}
|
||||
|
||||
cfg_match! {
|
||||
cfg(test) => {
|
||||
test => {
|
||||
use core::option::Option as Option3;
|
||||
fn works4() -> Option3<u32> { Some(1) }
|
||||
}
|
||||
}
|
||||
|
||||
cfg_match! {
|
||||
cfg(feature = "foo") => { fn works5() -> bool { false } }
|
||||
cfg(test) => { fn works5() -> bool { true } }
|
||||
feature = "foo" => { fn works5() -> bool { false } }
|
||||
test => { fn works5() -> bool { true } }
|
||||
}
|
||||
|
||||
assert!(works1().is_some());
|
||||
|
@ -154,7 +154,7 @@ fn cfg_match_options() {
|
|||
#[test]
|
||||
fn cfg_match_two_functions() {
|
||||
cfg_match! {
|
||||
cfg(target_pointer_width = "64") => {
|
||||
target_pointer_width = "64" => {
|
||||
fn foo1() {}
|
||||
fn bar1() {}
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ fn cfg_match_two_functions() {
|
|||
|
||||
fn _accepts_expressions() -> i32 {
|
||||
cfg_match! {
|
||||
cfg(unix) => { 1 }
|
||||
unix => { 1 }
|
||||
_ => { 2 }
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +189,18 @@ fn _allows_stmt_expr_attributes() {
|
|||
let one = 1;
|
||||
let two = 2;
|
||||
cfg_match! {
|
||||
cfg(unix) => { one * two; }
|
||||
unix => { one * two; }
|
||||
_ => { one + two; }
|
||||
}
|
||||
}
|
||||
|
||||
fn _expression() {
|
||||
let _ = cfg_match!({
|
||||
windows => {
|
||||
" XP"
|
||||
}
|
||||
_ => {
|
||||
""
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
193
library/core/tests/macros_bootstrap.rs
Normal file
193
library/core/tests/macros_bootstrap.rs
Normal file
|
@ -0,0 +1,193 @@
|
|||
#![allow(unused_must_use)]
|
||||
|
||||
#[allow(dead_code)]
|
||||
trait Trait {
|
||||
fn blah(&self);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Struct;
|
||||
|
||||
impl Trait for Struct {
|
||||
cfg_match! {
|
||||
cfg(feature = "blah") => {
|
||||
fn blah(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
fn blah(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn assert_eq_trailing_comma() {
|
||||
assert_eq!(1, 1,);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn assert_escape() {
|
||||
assert!(r#"☃\backslash"#.contains("\\"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn assert_ne_trailing_comma() {
|
||||
assert_ne!(1, 2,);
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[test]
|
||||
fn matches_leading_pipe() {
|
||||
matches!(1, | 1 | 2 | 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cfg_match_basic() {
|
||||
cfg_match! {
|
||||
cfg(target_pointer_width = "64") => { fn f0_() -> bool { true }}
|
||||
}
|
||||
|
||||
cfg_match! {
|
||||
cfg(unix) => { fn f1_() -> bool { true }}
|
||||
cfg(any(target_os = "macos", target_os = "linux")) => { fn f1_() -> bool { false }}
|
||||
}
|
||||
|
||||
cfg_match! {
|
||||
cfg(target_pointer_width = "32") => { fn f2_() -> bool { false }}
|
||||
cfg(target_pointer_width = "64") => { fn f2_() -> bool { true }}
|
||||
}
|
||||
|
||||
cfg_match! {
|
||||
cfg(target_pointer_width = "16") => { fn f3_() -> i32 { 1 }}
|
||||
_ => { fn f3_() -> i32 { 2 }}
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
assert!(f0_());
|
||||
|
||||
#[cfg(unix)]
|
||||
assert!(f1_());
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
assert!(!f2_());
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
assert!(f2_());
|
||||
|
||||
#[cfg(not(target_pointer_width = "16"))]
|
||||
assert_eq!(f3_(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cfg_match_debug_assertions() {
|
||||
cfg_match! {
|
||||
cfg(debug_assertions) => {
|
||||
assert!(cfg!(debug_assertions));
|
||||
assert_eq!(4, 2+2);
|
||||
}
|
||||
_ => {
|
||||
assert!(cfg!(not(debug_assertions)));
|
||||
assert_eq!(10, 5+5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
#[test]
|
||||
fn cfg_match_no_duplication_on_64() {
|
||||
cfg_match! {
|
||||
cfg(windows) => {
|
||||
fn foo() {}
|
||||
}
|
||||
cfg(unix) => {
|
||||
fn foo() {}
|
||||
}
|
||||
cfg(target_pointer_width = "64") => {
|
||||
fn foo() {}
|
||||
}
|
||||
}
|
||||
foo();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cfg_match_options() {
|
||||
cfg_match! {
|
||||
cfg(test) => {
|
||||
use core::option::Option as Option2;
|
||||
fn works1() -> Option2<u32> { Some(1) }
|
||||
}
|
||||
_ => { fn works1() -> Option<u32> { None } }
|
||||
}
|
||||
|
||||
cfg_match! {
|
||||
cfg(feature = "foo") => { fn works2() -> bool { false } }
|
||||
cfg(test) => { fn works2() -> bool { true } }
|
||||
_ => { fn works2() -> bool { false } }
|
||||
}
|
||||
|
||||
cfg_match! {
|
||||
cfg(feature = "foo") => { fn works3() -> bool { false } }
|
||||
_ => { fn works3() -> bool { true } }
|
||||
}
|
||||
|
||||
cfg_match! {
|
||||
cfg(test) => {
|
||||
use core::option::Option as Option3;
|
||||
fn works4() -> Option3<u32> { Some(1) }
|
||||
}
|
||||
}
|
||||
|
||||
cfg_match! {
|
||||
cfg(feature = "foo") => { fn works5() -> bool { false } }
|
||||
cfg(test) => { fn works5() -> bool { true } }
|
||||
}
|
||||
|
||||
assert!(works1().is_some());
|
||||
assert!(works2());
|
||||
assert!(works3());
|
||||
assert!(works4().is_some());
|
||||
assert!(works5());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cfg_match_two_functions() {
|
||||
cfg_match! {
|
||||
cfg(target_pointer_width = "64") => {
|
||||
fn foo1() {}
|
||||
fn bar1() {}
|
||||
}
|
||||
_ => {
|
||||
fn foo2() {}
|
||||
fn bar2() {}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
{
|
||||
foo1();
|
||||
bar1();
|
||||
}
|
||||
#[cfg(not(target_pointer_width = "64"))]
|
||||
{
|
||||
foo2();
|
||||
bar2();
|
||||
}
|
||||
}
|
||||
|
||||
fn _accepts_expressions() -> i32 {
|
||||
cfg_match! {
|
||||
cfg(unix) => { 1 }
|
||||
_ => { 2 }
|
||||
}
|
||||
}
|
||||
|
||||
fn _allows_stmt_expr_attributes() {
|
||||
let one = 1;
|
||||
let two = 2;
|
||||
cfg_match! {
|
||||
cfg(unix) => { one * two; }
|
||||
_ => { one + two; }
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue