From 77471c4ac856fbe54a396b630b1610aea3bd18e2 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 15 Dec 2025 15:34:41 -0800 Subject: [PATCH 1/2] Make `PrimitiveFloatToInt` a supertrait of `PrimitiveFloat` --- src/float.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/tests.rs | 12 +----------- 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/src/float.rs b/src/float.rs index b9133df..8d501b7 100644 --- a/src/float.rs +++ b/src/float.rs @@ -54,7 +54,22 @@ struct SealedToken; /// assert_eq!(distance_squared::(&[0., 1., 2.], &[1., 3., 0.]), 9.); /// ``` pub trait PrimitiveFloat: - PrimitiveNumber + From + From + core::ops::Neg + PrimitiveNumber + + PrimitiveFloatToInt + + PrimitiveFloatToInt + + PrimitiveFloatToInt + + PrimitiveFloatToInt + + PrimitiveFloatToInt + + PrimitiveFloatToInt + + PrimitiveFloatToInt + + PrimitiveFloatToInt + + PrimitiveFloatToInt + + PrimitiveFloatToInt + + PrimitiveFloatToInt + + PrimitiveFloatToInt + + core::convert::From + + core::convert::From + + core::ops::Neg { /// Approximate number of significant digits in base 10. const DIGITS: u32; @@ -405,7 +420,42 @@ pub trait PrimitiveFloatRef: PrimitiveNumberRef + core::ops::Neg: PrimitiveFloat { +/// +/// # Examples +/// +/// `PrimitiveFloatToInt<{integer}>` is a supertrait of [`PrimitiveFloat`] for all primitive +/// integers, so you do not need to use this trait directly with concrete integer types. +/// +/// ``` +/// use num_primitive::PrimitiveFloat; +/// +/// fn pi() -> i32 { +/// // SAFETY: π is finite, and truncated to 3 fits any int +/// unsafe { Float::PI.to_int_unchecked() } +/// } +/// +/// assert_eq!(pi::(), 3i32); +/// assert_eq!(pi::(), 3i32); +/// ``` +/// +/// However, if the integer type is also generic, an explicit type constraint is needed. +/// +/// ``` +/// use num_primitive::{PrimitiveFloat, PrimitiveFloatToInt}; +/// +/// fn tau() -> Int +/// where +/// Float: PrimitiveFloat + PrimitiveFloatToInt, +/// { +/// // SAFETY: τ is finite, and truncated to 6 fits any int +/// unsafe { Float::TAU.to_int_unchecked() } +/// } +/// +/// assert_eq!(tau::(), 6i64); +/// assert_eq!(tau::(), 6u8); +/// ``` +/// +pub trait PrimitiveFloatToInt { #[doc(hidden)] #[expect(private_interfaces)] unsafe fn __to_int_unchecked(x: Self, _: SealedToken) -> Int; diff --git a/src/tests.rs b/src/tests.rs index 1cf731c..6b5d08f 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -17,7 +17,7 @@ extern crate alloc; use alloc::boxed::Box; use core::error::Error; -use crate::{PrimitiveError, PrimitiveFloatToInt, PrimitiveInteger, PrimitiveNumber}; +use crate::{PrimitiveError, PrimitiveInteger, PrimitiveNumber}; fn check_result<'a, T: PrimitiveNumber, E: PrimitiveError>(r: Result, ok: T) { // Cloning and equating results requires `E: Clone + PartialEq` @@ -58,13 +58,3 @@ fn try_into() { } check(0i32, 0u32); } - -#[test] -fn to_int_unchecked() { - fn pi, Int>() -> Int { - // SAFETY: π is finite, and truncated to 3 fits any int - unsafe { T::PI.to_int_unchecked() } - } - assert_eq!(pi::(), 3i64); - assert_eq!(pi::(), 3u8); -} From 34bb21b469052757a6d1058c313d7acd36553110 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 15 Dec 2025 15:40:20 -0800 Subject: [PATCH 2/2] Bump to semver 0.2 --- .gitignore | 1 + Cargo.lock | 7 ------- Cargo.toml | 2 +- 3 files changed, 2 insertions(+), 8 deletions(-) delete mode 100644 Cargo.lock diff --git a/.gitignore b/.gitignore index ea8c4bf..1b72444 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ +/Cargo.lock /target diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index 18764f0..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "num-primitive" -version = "0.1.1" diff --git a/Cargo.toml b/Cargo.toml index bdf3ce8..9d805f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "num-primitive" -version = "0.1.1" +version = "0.2.0" description = "Traits for primitive numeric types" repository = "https://github.com/rust-num/num-primitive" license = "MIT OR Apache-2.0"