Преглед изворни кода

Add public-test-deps feature for better visibility control

Aaron Kutch пре 3 година
родитељ
комит
2ad41ef64b

+ 4 - 0
Cargo.toml

@@ -64,6 +64,10 @@ no-lang-items = []
 # Only used in the compiler's build system
 rustc-dep-of-std = ['compiler-builtins', 'core']
 
+# This makes certain traits and function specializations public that
+# are not normally public but are required by the `testcrate`
+public-test-deps = []
+
 [[example]]
 name = "intrinsics"
 required-features = ["compiler-builtins"]

+ 3 - 2
src/float/mod.rs

@@ -11,9 +11,9 @@ pub mod mul;
 pub mod pow;
 pub mod sub;
 
+public_test_dep! {
 /// Trait for some basic operations on floats
-#[doc(hidden)]
-pub trait Float:
+pub(crate) trait Float:
     Copy
     + core::fmt::Debug
     + PartialEq
@@ -99,6 +99,7 @@ pub trait Float:
     /// Returns if `self` is subnormal
     fn is_subnormal(self) -> bool;
 }
+}
 
 macro_rules! float_impl {
     ($ty:ident, $ity:ident, $sity:ident, $expty:ident, $bits:expr, $significand_bits:expr) => {

+ 6 - 4
src/int/leading_zeros.rs

@@ -3,9 +3,9 @@
 // adding a zero check at the beginning, but `__clzsi2` has a precondition that `x != 0`.
 // Compilers will insert the check for zero in cases where it is needed.
 
+public_test_dep! {
 /// Returns the number of leading binary zeros in `x`.
-#[doc(hidden)]
-pub fn usize_leading_zeros_default(x: usize) -> usize {
+pub(crate) fn usize_leading_zeros_default(x: usize) -> usize {
     // The basic idea is to test if the higher bits of `x` are zero and bisect the number
     // of leading zeros. It is possible for all branches of the bisection to use the same
     // code path by conditionally shifting the higher parts down to let the next bisection
@@ -69,15 +69,16 @@ pub fn usize_leading_zeros_default(x: usize) -> usize {
     // on x86_64, it is slightly faster to use the LUT, but this is probably because of OOO
     // execution effects. Changing to using a LUT and branching is risky for smaller cores.
 }
+}
 
 // The above method does not compile well on RISC-V (because of the lack of predicated
 // instructions), producing code with many branches or using an excessively long
 // branchless solution. This method takes advantage of the set-if-less-than instruction on
 // RISC-V that allows `(x >= power-of-two) as usize` to be branchless.
 
+public_test_dep! {
 /// Returns the number of leading binary zeros in `x`.
-#[doc(hidden)]
-pub fn usize_leading_zeros_riscv(x: usize) -> usize {
+pub(crate) fn usize_leading_zeros_riscv(x: usize) -> usize {
     let mut x = x;
     // the number of potential leading zeros
     let mut z = usize::MAX.count_ones() as usize;
@@ -126,6 +127,7 @@ pub fn usize_leading_zeros_riscv(x: usize) -> usize {
     // If `x != 0` then `x == 1` and subtracts one potential zero from `z`.
     z - x
 }
+}
 
 intrinsics! {
     #[maybe_use_optimized_c_shim]

+ 12 - 8
src/int/mod.rs

@@ -11,9 +11,9 @@ pub mod udiv;
 
 pub use self::leading_zeros::__clzsi2;
 
+public_test_dep! {
 /// Trait for some basic operations on integers
-#[doc(hidden)]
-pub trait Int:
+pub(crate) trait Int:
     Copy
     + core::fmt::Debug
     + PartialEq
@@ -81,6 +81,7 @@ pub trait Int:
     fn overflowing_add(self, other: Self) -> (Self, bool);
     fn leading_zeros(self) -> u32;
 }
+}
 
 macro_rules! int_impl_common {
     ($ty:ty) => {
@@ -255,10 +256,10 @@ int_impl!(i32, u32);
 int_impl!(i64, u64);
 int_impl!(i128, u128);
 
+public_test_dep! {
 /// Trait for integers twice the bit width of another integer. This is implemented for all
 /// primitives except for `u8`, because there is not a smaller primitive.
-#[doc(hidden)]
-pub trait DInt: Int {
+pub(crate) trait DInt: Int {
     /// Integer that is half the bit width of the integer this trait is implemented for
     type H: HInt<D = Self> + Int;
 
@@ -271,11 +272,12 @@ pub trait DInt: Int {
     /// Constructs an integer using lower and higher half parts
     fn from_lo_hi(lo: Self::H, hi: Self::H) -> Self;
 }
+}
 
+public_test_dep! {
 /// Trait for integers half the bit width of another integer. This is implemented for all
 /// primitives except for `u128`, because it there is not a larger primitive.
-#[doc(hidden)]
-pub trait HInt: Int {
+pub(crate) trait HInt: Int {
     /// Integer that is double the bit width of the integer this trait is implemented for
     type D: DInt<H = Self> + Int;
 
@@ -291,6 +293,7 @@ pub trait HInt: Int {
     /// Widening multiplication. This cannot overflow.
     fn widen_mul(self, rhs: Self) -> Self::D;
 }
+}
 
 macro_rules! impl_d_int {
     ($($X:ident $D:ident),*) => {
@@ -353,11 +356,12 @@ impl_h_int!(
     i64 u64 i128
 );
 
+public_test_dep! {
 /// Trait to express (possibly lossy) casting of integers
-#[doc(hidden)]
-pub trait CastInto<T: Copy>: Copy {
+pub(crate) trait CastInto<T: Copy>: Copy {
     fn cast(self) -> T;
 }
+}
 
 macro_rules! cast_into {
     ($ty:ty) => {

+ 1 - 2
src/int/specialized_div_rem/asymmetric.rs

@@ -3,8 +3,7 @@
 /// assembly instruction that can divide a 128 bit integer by a 64 bit integer if the quotient fits
 /// in 64 bits. The 128 bit version of this algorithm would use that fast hardware division to
 /// construct a full 128 bit by 128 bit division.
-#[doc(hidden)]
-#[macro_export]
+#[allow(unused_macros)]
 macro_rules! impl_asymmetric {
     (
         $fn:ident, // name of the unsigned division function

+ 1 - 2
src/int/specialized_div_rem/binary_long.rs

@@ -4,8 +4,7 @@
 /// predicate instructions. For architectures with predicated instructions, one of the algorithms
 /// described in the documentation of these functions probably has higher performance, and a custom
 /// assembly routine should be used instead.
-#[doc(hidden)]
-#[macro_export]
+#[allow(unused_macros)]
 macro_rules! impl_binary_long {
     (
         $fn:ident, // name of the unsigned division function

+ 6 - 4
src/int/specialized_div_rem/delegate.rs

@@ -2,8 +2,7 @@
 /// binary long division to divide integers larger than what hardware division by itself can do. This
 /// function is intended for microarchitectures that have division hardware, but not fast enough
 /// multiplication hardware for `impl_trifecta` to be faster.
-#[doc(hidden)]
-#[macro_export]
+#[allow(unused_macros)]
 macro_rules! impl_delegate {
     (
         $fn:ident, // name of the unsigned division function
@@ -186,6 +185,7 @@ macro_rules! impl_delegate {
     };
 }
 
+public_test_dep! {
 /// Returns `n / d` and sets `*rem = n % d`.
 ///
 /// This specialization exists because:
@@ -193,8 +193,9 @@ macro_rules! impl_delegate {
 ///    so we have to use an old fashioned `&mut u128` argument to return the remainder.
 ///  - 64-bit SPARC does not have u64 * u64 => u128 widening multiplication, which makes the
 ///    delegate algorithm strategy the only reasonably fast way to perform `u128` division.
-#[doc(hidden)]
-pub fn u128_divide_sparc(duo: u128, div: u128, rem: &mut u128) -> u128 {
+// used on SPARC
+#[allow(dead_code)]
+pub(crate) fn u128_divide_sparc(duo: u128, div: u128, rem: &mut u128) -> u128 {
     use super::*;
     let duo_lo = duo as u64;
     let duo_hi = (duo >> 64) as u64;
@@ -315,3 +316,4 @@ pub fn u128_divide_sparc(duo: u128, div: u128, rem: &mut u128) -> u128 {
         }
     }
 }
+}

+ 7 - 0
src/int/specialized_div_rem/mod.rs

@@ -53,6 +53,13 @@ mod binary_long;
 
 #[macro_use]
 mod delegate;
+
+// used on SPARC
+#[allow(unused_imports)]
+#[cfg(not(feature = "public-test-deps"))]
+pub(crate) use self::delegate::u128_divide_sparc;
+
+#[cfg(feature = "public-test-deps")]
 pub use self::delegate::u128_divide_sparc;
 
 #[macro_use]

+ 1 - 2
src/int/specialized_div_rem/norm_shift.rs

@@ -1,6 +1,5 @@
 /// Creates a function used by some division algorithms to compute the "normalization shift".
-#[doc(hidden)]
-#[macro_export]
+#[allow(unused_macros)]
 macro_rules! impl_normalization_shift {
     (
         $name:ident, // name of the normalization shift function

+ 1 - 2
src/int/specialized_div_rem/trifecta.rs

@@ -2,8 +2,7 @@
 /// larger than the largest hardware integer division supported. These functions use large radix
 /// division algorithms that require both fast division and very fast widening multiplication on the
 /// target microarchitecture. Otherwise, `impl_delegate` should be used instead.
-#[doc(hidden)]
-#[macro_export]
+#[allow(unused_macros)]
 macro_rules! impl_trifecta {
     (
         $fn:ident, // name of the unsigned division function

+ 5 - 2
src/int/udiv.rs

@@ -1,5 +1,8 @@
-pub use int::specialized_div_rem::u128_divide_sparc;
-use int::specialized_div_rem::*;
+#[cfg(not(feature = "public-test-deps"))]
+pub(crate) use int::specialized_div_rem::*;
+
+#[cfg(feature = "public-test-deps")]
+pub use int::specialized_div_rem::*;
 
 intrinsics! {
     #[maybe_use_optimized_c_shim]

+ 16 - 0
src/macros.rs

@@ -1,5 +1,21 @@
 //! Macros shared throughout the compiler-builtins implementation
 
+/// Changes the visibility to `pub` if feature "public-test-deps" is set
+#[cfg(not(feature = "public-test-deps"))]
+macro_rules! public_test_dep {
+    ($(#[$($meta:meta)*])* pub(crate) $ident:ident $($tokens:tt)*) => {
+        $(#[$($meta)*])* pub(crate) $ident $($tokens)*
+    };
+}
+
+/// Changes the visibility to `pub` if feature "public-test-deps" is set
+#[cfg(feature = "public-test-deps")]
+macro_rules! public_test_dep {
+    {$(#[$($meta:meta)*])* pub(crate) $ident:ident $($tokens:tt)*} => {
+        $(#[$($meta)*])* pub $ident $($tokens)*
+    };
+}
+
 /// The "main macro" used for defining intrinsics.
 ///
 /// The compiler-builtins library is super platform-specific with tons of crazy

+ 1 - 1
testcrate/Cargo.toml

@@ -17,7 +17,7 @@ rand_xoshiro = "0.6"
 [dependencies.compiler_builtins]
 path = ".."
 default-features = false
-features = ["no-lang-items"]
+features = ["no-lang-items", "public-test-deps"]
 
 [target.'cfg(all(target_arch = "arm", not(any(target_env = "gnu", target_env = "musl")), target_os = "linux"))'.dev-dependencies]
 test = { git = "https://github.com/japaric/utest" }