mirror of
https://github.com/rust-lang/rust.git
synced 2025-10-08 21:31:32 +00:00

These are never available in musl, so introduce easier ways to skip them rather than needing to exclude f16/f128 functions in three different places.
178 lines
4.2 KiB
Rust
178 lines
4.2 KiB
Rust
#![feature(f16)]
|
|
#![feature(f128)]
|
|
// `STATUS_DLL_NOT_FOUND` on i686 MinGW, not worth looking into.
|
|
#![cfg(not(all(target_arch = "x86", target_os = "windows", target_env = "gnu")))]
|
|
|
|
macro_rules! basic {
|
|
(
|
|
fn_name: $fn_name:ident,
|
|
FTy: $FTy:ty,
|
|
CFn: $CFn:ty,
|
|
CArgs: $CArgs:ty,
|
|
CRet: $CRet:ty,
|
|
RustFn: $RustFn:ty,
|
|
RustArgs: $RustArgs:ty,
|
|
RustRet: $RustRet:ty,
|
|
public: $public:expr,
|
|
attrs: [$($attr:meta),*],
|
|
extra: [$($extra_tt:tt)*],
|
|
fn_extra: $fn_extra:expr,
|
|
) => {
|
|
$(#[$attr])*
|
|
#[allow(dead_code)]
|
|
pub mod $fn_name {
|
|
type FTy= $FTy;
|
|
type CFnTy<'a> = $CFn;
|
|
type RustFnTy = $RustFn;
|
|
type RustArgsTy = $RustArgs;
|
|
type RustRetTy = $RustRet;
|
|
const PUBLIC: bool = $public;
|
|
const A: &[&str] = &[$($extra_tt)*];
|
|
fn foo(a: f32) -> f32 {
|
|
$fn_extra(a)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
mod test_basic {
|
|
libm_macros::for_each_function! {
|
|
callback: basic,
|
|
emit_types: all,
|
|
skip: [sin, cos],
|
|
attributes: [
|
|
// just some random attributes
|
|
#[allow(clippy::pedantic)]
|
|
#[allow(dead_code)]
|
|
[sinf, cosf]
|
|
],
|
|
extra: ["foo", "bar"],
|
|
fn_extra: match MACRO_FN_NAME {
|
|
sin => |x| x + 2.0,
|
|
cos | cosf => |x: f32| x.MACRO_FN_NAME_NORMALIZED(),
|
|
_ => |_x| 100.0
|
|
}
|
|
}
|
|
}
|
|
|
|
macro_rules! basic_no_extra {
|
|
(
|
|
fn_name: $fn_name:ident,
|
|
attrs: [$($attr:meta),*],
|
|
) => {
|
|
$(#[$attr])*
|
|
mod $fn_name {}
|
|
};
|
|
}
|
|
|
|
mod test_basic_no_extra {
|
|
// Test with no extra, no skip, and no attributes
|
|
libm_macros::for_each_function! {
|
|
callback: basic_no_extra,
|
|
}
|
|
}
|
|
|
|
mod test_only {
|
|
// Test that only works
|
|
libm_macros::for_each_function! {
|
|
callback: basic_no_extra,
|
|
only: [sin, sinf],
|
|
}
|
|
}
|
|
|
|
macro_rules! specified_types {
|
|
(
|
|
fn_name: $fn_name:ident,
|
|
RustFn: $RustFn:ty,
|
|
RustArgs: $RustArgs:ty,
|
|
attrs: [$($attr:meta),*],
|
|
) => {
|
|
$(#[$attr])*
|
|
#[allow(dead_code)]
|
|
mod $fn_name {
|
|
type RustFnTy = $RustFn;
|
|
type RustArgsTy = $RustArgs;
|
|
}
|
|
};
|
|
}
|
|
|
|
mod test_emit_types {
|
|
// Test that we can specify a couple types to emit
|
|
libm_macros::for_each_function! {
|
|
callback: specified_types,
|
|
emit_types: [RustFn, RustArgs],
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_skip_f16_f128() {
|
|
macro_rules! skip_f16_f128 {
|
|
(
|
|
fn_name: $fn_name:ident,
|
|
attrs: [$($attr:meta),*],
|
|
extra: $vec:ident,
|
|
) => {
|
|
$vec.push(stringify!($fn_name));
|
|
};
|
|
}
|
|
|
|
let mut v = Vec::new();
|
|
// Test with no extra, no skip, and no attributes
|
|
libm_macros::for_each_function! {
|
|
callback: skip_f16_f128,
|
|
skip_f16_f128: true,
|
|
extra: v,
|
|
}
|
|
|
|
for name in v {
|
|
assert!(!name.contains("f16"), "{name}");
|
|
assert!(!name.contains("f128"), "{name}");
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_fn_extra_expansion() {
|
|
macro_rules! fn_extra_expansion {
|
|
(
|
|
fn_name: $fn_name:ident,
|
|
attrs: [$($attr:meta),*],
|
|
fn_extra: $vec:expr,
|
|
) => {
|
|
$vec.push(stringify!($fn_name));
|
|
};
|
|
}
|
|
|
|
let mut vf16 = Vec::new();
|
|
let mut vf32 = Vec::new();
|
|
let mut vf64 = Vec::new();
|
|
let mut vf128 = Vec::new();
|
|
|
|
// Test with no extra, no skip, and no attributes
|
|
libm_macros::for_each_function! {
|
|
callback: fn_extra_expansion,
|
|
fn_extra: match MACRO_FN_NAME {
|
|
ALL_F16 => vf16,
|
|
ALL_F32 => vf32,
|
|
ALL_F64 => vf64,
|
|
ALL_F128 => vf128,
|
|
}
|
|
}
|
|
|
|
// Skip functions with a suffix after the type spec
|
|
vf16.retain(|name| !name.ends_with("_r"));
|
|
vf32.retain(|name| !name.ends_with("_r"));
|
|
vf64.retain(|name| !name.ends_with("_r"));
|
|
vf128.retain(|name| !name.ends_with("_r"));
|
|
|
|
for name in vf16 {
|
|
assert!(name.ends_with("f16"), "{name}");
|
|
}
|
|
for name in vf32 {
|
|
assert!(name.ends_with("f"), "{name}");
|
|
}
|
|
let _ = vf64;
|
|
for name in vf128 {
|
|
assert!(name.ends_with("f128"), "{name}");
|
|
}
|
|
}
|