Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use namespaced-features to safely bump to MSRV 1.60 #310

Merged
merged 12 commits into from Mar 25, 2024
8 changes: 1 addition & 7 deletions .github/workflows/ci.yaml
Expand Up @@ -9,13 +9,7 @@ jobs:
strategy:
matrix:
rust: [
1.31.0, # MSRV
1.35.0, # has_copysign
1.37.0, # has_reverse_bits
1.38.0, # has_div_euclid
1.44.0, # has_to_int_unchecked
1.46.0, # has_leading_trailing_ones
1.53.0, # has_is_subnormal
1.60.0, # MSRV
1.62.0, # has_total_cmp
stable,
beta,
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/master.yaml
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
rust: [1.31.0, stable]
rust: [1.60.0, stable]
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr.yaml
Expand Up @@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
rust: [1.31.0, stable]
rust: [1.60.0, stable]
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
Expand Down
5 changes: 3 additions & 2 deletions Cargo.toml
Expand Up @@ -12,8 +12,8 @@ version = "0.2.18"
readme = "README.md"
build = "build.rs"
exclude = ["/ci/*", "/.github/*"]
edition = "2018"
rust-version = "1.31"
edition = "2021"
rust-version = "1.60"

[package.metadata.docs.rs]
features = ["std"]
Expand All @@ -24,6 +24,7 @@ libm = { version = "0.2.0", optional = true }

[features]
default = ["std"]
libm = ["dep:libm"]
std = []

# vestigial features, now always in effect
Expand Down
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -2,7 +2,7 @@

[![crate](https://img.shields.io/crates/v/num-traits.svg)](https://crates.io/crates/num-traits)
[![documentation](https://docs.rs/num-traits/badge.svg)](https://docs.rs/num-traits)
[![minimum rustc 1.31](https://img.shields.io/badge/rustc-1.31+-red.svg)](https://rust-lang.github.io/rfcs/2495-min-rust-version.html)
[![minimum rustc 1.60](https://img.shields.io/badge/rustc-1.60+-red.svg)](https://rust-lang.github.io/rfcs/2495-min-rust-version.html)
[![build status](https://github.com/rust-num/num-traits/workflows/master/badge.svg)](https://github.com/rust-num/num-traits/actions)

Numeric traits for generic mathematics in Rust.
Expand Down Expand Up @@ -40,7 +40,7 @@ Release notes are available in [RELEASES.md](RELEASES.md).

## Compatibility

The `num-traits` crate is tested for rustc 1.31 and greater.
The `num-traits` crate is tested for rustc 1.60 and greater.

## License

Expand Down
20 changes: 1 addition & 19 deletions build.rs
@@ -1,25 +1,7 @@
use std::env;

fn main() {
let ac = autocfg::new();

ac.emit_expression_cfg(
"unsafe { 1f64.to_int_unchecked::<i32>() }",
"has_to_int_unchecked",
);

ac.emit_expression_cfg("1u32.reverse_bits()", "has_reverse_bits");
ac.emit_expression_cfg("1u32.trailing_ones()", "has_leading_trailing_ones");
ac.emit_expression_cfg("1u32.div_euclid(1u32)", "has_div_euclid");

if env::var_os("CARGO_FEATURE_STD").is_some() {
ac.emit_expression_cfg("1f64.copysign(-1f64)", "has_copysign");
}
ac.emit_expression_cfg("1f64.is_subnormal()", "has_is_subnormal");
ac.emit_expression_cfg("1f64.total_cmp(&2f64)", "has_total_cmp");

ac.emit_expression_cfg("1u32.to_ne_bytes()", "has_int_to_from_bytes");
ac.emit_expression_cfg("3.14f64.to_ne_bytes()", "has_float_to_from_bytes");
ac.emit_expression_cfg("1f64.total_cmp(&2f64)", "has_total_cmp"); // 1.62

autocfg::rerun_path("build.rs");
}
2 changes: 1 addition & 1 deletion ci/rustup.sh
Expand Up @@ -5,6 +5,6 @@
set -ex

ci=$(dirname $0)
for version in 1.31.0 1.35.0 1.37.0 1.38.0 1.44.0 1.46.0 1.53.0 1.62.0 stable beta nightly; do
for version in 1.60.0 1.62.0 stable beta nightly; do
rustup run "$version" "$ci/test_full.sh"
done
5 changes: 1 addition & 4 deletions ci/test_full.sh
Expand Up @@ -3,7 +3,7 @@
set -e

CRATE=num-traits
MSRV=1.31
MSRV=1.60

get_rust_version() {
local array=($(rustc --version));
Expand Down Expand Up @@ -32,9 +32,6 @@ echo "Testing supported features: ${FEATURES[*]}"

cargo generate-lockfile

# libm 0.2.6 started using {float}::EPSILON
check_version 1.43 || cargo update -p libm --precise 0.2.5

set -x

# test the default
Expand Down
8 changes: 0 additions & 8 deletions src/cast.rs
Expand Up @@ -277,7 +277,6 @@ macro_rules! impl_to_primitive_float_to_float {
)*}
}

#[cfg(has_to_int_unchecked)]
macro_rules! float_to_int_unchecked {
// SAFETY: Must not be NaN or infinite; must be representable as the integer after truncating.
// We already checked that the float is in the exclusive range `(MIN-1, MAX+1)`.
Expand All @@ -286,13 +285,6 @@ macro_rules! float_to_int_unchecked {
};
}

#[cfg(not(has_to_int_unchecked))]
macro_rules! float_to_int_unchecked {
($float:expr => $int:ty) => {
$float as $int
};
}

macro_rules! impl_to_primitive_float_to_signed_int {
($f:ident : $( $(#[$cfg:meta])* fn $method:ident -> $i:ident ; )*) => {$(
#[inline]
Expand Down
28 changes: 4 additions & 24 deletions src/float.rs
Expand Up @@ -790,6 +790,7 @@ impl FloatCore for f32 {
Self::is_infinite(self) -> bool;
Self::is_finite(self) -> bool;
Self::is_normal(self) -> bool;
Self::is_subnormal(self) -> bool;
Self::classify(self) -> FpCategory;
Self::is_sign_positive(self) -> bool;
Self::is_sign_negative(self) -> bool;
Expand All @@ -800,11 +801,6 @@ impl FloatCore for f32 {
Self::to_radians(self) -> Self;
}

#[cfg(has_is_subnormal)]
forward! {
Self::is_subnormal(self) -> bool;
}

#[cfg(feature = "std")]
forward! {
Self::floor(self) -> Self;
Expand Down Expand Up @@ -855,6 +851,7 @@ impl FloatCore for f64 {
Self::is_infinite(self) -> bool;
Self::is_finite(self) -> bool;
Self::is_normal(self) -> bool;
Self::is_subnormal(self) -> bool;
Self::classify(self) -> FpCategory;
Self::is_sign_positive(self) -> bool;
Self::is_sign_negative(self) -> bool;
Expand All @@ -865,11 +862,6 @@ impl FloatCore for f64 {
Self::to_radians(self) -> Self;
}

#[cfg(has_is_subnormal)]
forward! {
Self::is_subnormal(self) -> bool;
}

#[cfg(feature = "std")]
forward! {
Self::floor(self) -> Self;
Expand Down Expand Up @@ -1901,6 +1893,7 @@ macro_rules! float_impl_std {
Self::is_infinite(self) -> bool;
Self::is_finite(self) -> bool;
Self::is_normal(self) -> bool;
Self::is_subnormal(self) -> bool;
Self::classify(self) -> FpCategory;
Self::floor(self) -> Self;
Self::ceil(self) -> Self;
Expand Down Expand Up @@ -1944,17 +1937,8 @@ macro_rules! float_impl_std {
Self::asinh(self) -> Self;
Self::acosh(self) -> Self;
Self::atanh(self) -> Self;
}

#[cfg(has_copysign)]
forward! {
Self::copysign(self, sign: Self) -> Self;
}

#[cfg(has_is_subnormal)]
forward! {
Self::is_subnormal(self) -> bool;
}
}
};
}
Expand Down Expand Up @@ -1993,6 +1977,7 @@ macro_rules! float_impl_libm {
Self::is_infinite(self) -> bool;
Self::is_finite(self) -> bool;
Self::is_normal(self) -> bool;
Self::is_subnormal(self) -> bool;
Self::classify(self) -> FpCategory;
Self::is_sign_positive(self) -> bool;
Self::is_sign_negative(self) -> bool;
Expand All @@ -2003,11 +1988,6 @@ macro_rules! float_impl_libm {
Self::to_radians(self) -> Self;
}

#[cfg(has_is_subnormal)]
forward! {
Self::is_subnormal(self) -> bool;
}

forward! {
FloatCore::signum(self) -> Self;
FloatCore::powi(self, n: i32) -> Self;
Expand Down
3 changes: 0 additions & 3 deletions src/int.rs
Expand Up @@ -404,7 +404,6 @@ macro_rules! prim_int_impl {
<$T>::count_zeros(self)
}

#[cfg(has_leading_trailing_ones)]
#[inline]
fn leading_ones(self) -> u32 {
<$T>::leading_ones(self)
Expand All @@ -415,7 +414,6 @@ macro_rules! prim_int_impl {
<$T>::leading_zeros(self)
}

#[cfg(has_leading_trailing_ones)]
#[inline]
fn trailing_ones(self) -> u32 {
<$T>::trailing_ones(self)
Expand Down Expand Up @@ -461,7 +459,6 @@ macro_rules! prim_int_impl {
<$T>::swap_bytes(self)
}

#[cfg(has_reverse_bits)]
#[inline]
fn reverse_bits(self) -> Self {
<$T>::reverse_bits(self)
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Expand Up @@ -12,7 +12,7 @@
//!
//! ## Compatibility
//!
//! The `num-traits` crate is tested for rustc 1.31 and greater.
//! The `num-traits` crate is tested for rustc 1.60 and greater.

#![doc(html_root_url = "https://docs.rs/num-traits/0.2")]
#![deny(unconditional_recursion)]
Expand Down
86 changes: 0 additions & 86 deletions src/ops/bytes.rs
Expand Up @@ -2,8 +2,6 @@ use core::borrow::{Borrow, BorrowMut};
use core::cmp::{Eq, Ord, PartialEq, PartialOrd};
use core::fmt::Debug;
use core::hash::Hash;
#[cfg(not(has_int_to_from_bytes))]
use core::mem::transmute;

pub trait NumBytes:
Debug
Expand Down Expand Up @@ -152,7 +150,6 @@ pub trait FromBytes: Sized {

macro_rules! float_to_from_bytes_impl {
($T:ty, $L:expr) => {
#[cfg(has_float_to_from_bytes)]
impl ToBytes for $T {
type Bytes = [u8; $L];

Expand All @@ -172,7 +169,6 @@ macro_rules! float_to_from_bytes_impl {
}
}

#[cfg(has_float_to_from_bytes)]
impl FromBytes for $T {
type Bytes = [u8; $L];

Expand All @@ -191,52 +187,11 @@ macro_rules! float_to_from_bytes_impl {
<$T>::from_ne_bytes(*bytes)
}
}

#[cfg(not(has_float_to_from_bytes))]
impl ToBytes for $T {
type Bytes = [u8; $L];

#[inline]
fn to_be_bytes(&self) -> Self::Bytes {
ToBytes::to_be_bytes(&self.to_bits())
}

#[inline]
fn to_le_bytes(&self) -> Self::Bytes {
ToBytes::to_le_bytes(&self.to_bits())
}

#[inline]
fn to_ne_bytes(&self) -> Self::Bytes {
ToBytes::to_ne_bytes(&self.to_bits())
}
}

#[cfg(not(has_float_to_from_bytes))]
impl FromBytes for $T {
type Bytes = [u8; $L];

#[inline]
fn from_be_bytes(bytes: &Self::Bytes) -> Self {
Self::from_bits(FromBytes::from_be_bytes(bytes))
}

#[inline]
fn from_le_bytes(bytes: &Self::Bytes) -> Self {
Self::from_bits(FromBytes::from_le_bytes(bytes))
}

#[inline]
fn from_ne_bytes(bytes: &Self::Bytes) -> Self {
Self::from_bits(FromBytes::from_ne_bytes(bytes))
}
}
};
}

macro_rules! int_to_from_bytes_impl {
($T:ty, $L:expr) => {
#[cfg(has_int_to_from_bytes)]
impl ToBytes for $T {
type Bytes = [u8; $L];

Expand All @@ -256,7 +211,6 @@ macro_rules! int_to_from_bytes_impl {
}
}

#[cfg(has_int_to_from_bytes)]
impl FromBytes for $T {
type Bytes = [u8; $L];

Expand All @@ -275,46 +229,6 @@ macro_rules! int_to_from_bytes_impl {
<$T>::from_ne_bytes(*bytes)
}
}

#[cfg(not(has_int_to_from_bytes))]
impl ToBytes for $T {
type Bytes = [u8; $L];

#[inline]
fn to_be_bytes(&self) -> Self::Bytes {
<$T as ToBytes>::to_ne_bytes(&<$T>::to_be(*self))
}

#[inline]
fn to_le_bytes(&self) -> Self::Bytes {
<$T as ToBytes>::to_ne_bytes(&<$T>::to_le(*self))
}

#[inline]
fn to_ne_bytes(&self) -> Self::Bytes {
unsafe { transmute(*self) }
}
}

#[cfg(not(has_int_to_from_bytes))]
impl FromBytes for $T {
type Bytes = [u8; $L];

#[inline]
fn from_be_bytes(bytes: &Self::Bytes) -> Self {
Self::from_be(<Self as FromBytes>::from_ne_bytes(bytes))
}

#[inline]
fn from_le_bytes(bytes: &Self::Bytes) -> Self {
Self::from_le(<Self as FromBytes>::from_ne_bytes(bytes))
}

#[inline]
fn from_ne_bytes(bytes: &Self::Bytes) -> Self {
unsafe { transmute(*bytes) }
}
}
};
}

Expand Down