about summary refs log tree commit diff
path: root/library/compiler-builtins/crates/libm-macros/tests/basic.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-06-03 19:52:05 +0000
committerbors <bors@rust-lang.org>2025-06-03 19:52:05 +0000
commit59aa1e873028948faaf8b97e5e02d4db340ad7b1 (patch)
treee24e0d236c31a4f37fca6d5bf52b4ddaedf2f09a /library/compiler-builtins/crates/libm-macros/tests/basic.rs
parenta124fb3cb7291d75872934f411d81fe298379ace (diff)
parentaff21f659f5abeba49b05368affd8c829807b1f1 (diff)
downloadrust-59aa1e873028948faaf8b97e5e02d4db340ad7b1.tar.gz
rust-59aa1e873028948faaf8b97e5e02d4db340ad7b1.zip
Auto merge of #141229 - tgross35:builtins-josh-subtree, r=Kobzol
Merge `compiler-builtins` as a Josh subtree

Use the Josh [1] utility to add `compiler-builtins` as a subtree, which
will allow us to stop using crates.io for updates. This is intended to
help resolve some problems when unstable features change and require
code changes in `compiler-builtins`, which sometimes gets trapped in a
bootstrap cycle.

This was done using `josh-filter` built from the r24.10.04 tag:

    git fetch https://github.com/rust-lang/compiler-builtins.git 233434412fe7eced8f1ddbfeddabef1d55e493bd
    josh-filter ":prefix=library/compiler-builtins" FETCH_HEAD
    git merge --allow-unrelated FILTERED_HEAD

The HEAD in the `compiler-builtins` repository is 233434412f ("fix an if
statement that can be collapsed").

[1]: https://github.com/josh-project/josh
Diffstat (limited to 'library/compiler-builtins/crates/libm-macros/tests/basic.rs')
-rw-r--r--library/compiler-builtins/crates/libm-macros/tests/basic.rs177
1 files changed, 177 insertions, 0 deletions
diff --git a/library/compiler-builtins/crates/libm-macros/tests/basic.rs b/library/compiler-builtins/crates/libm-macros/tests/basic.rs
new file mode 100644
index 00000000000..b4276262229
--- /dev/null
+++ b/library/compiler-builtins/crates/libm-macros/tests/basic.rs
@@ -0,0 +1,177 @@
+#![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}");
+    }
+}