From d7213ca4e52f456beba45028bb34015529497056 Mon Sep 17 00:00:00 2001 From: Kyuuhachi Date: Tue, 16 Dec 2025 23:03:24 +0100 Subject: [PATCH 1/5] Implement clamp_to --- library/core/src/cmp.rs | 32 ++++++++++++ library/core/src/cmp/clamp.rs | 98 +++++++++++++++++++++++++++++++++++ library/core/src/num/f128.rs | 33 ++++++++++++ library/core/src/num/f16.rs | 33 ++++++++++++ library/core/src/num/f32.rs | 33 ++++++++++++ library/core/src/num/f64.rs | 33 ++++++++++++ 6 files changed, 262 insertions(+) create mode 100644 library/core/src/cmp/clamp.rs diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 2051a806af642..c147571a361a5 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -26,7 +26,10 @@ #![stable(feature = "rust1", since = "1.0.0")] mod bytewise; +mod clamp; pub(crate) use bytewise::BytewiseEq; +#[unstable(feature = "clamp_bounds", issue = "147781")] +pub use clamp::ClampBounds; use self::Ordering::*; use crate::marker::{Destruct, PointeeSized}; @@ -1108,6 +1111,35 @@ pub const trait Ord: [const] Eq + [const] PartialOrd + PointeeSized { self } } + + /// Restrict a value to a certain range. + /// + /// This is equal to `max`, `min`, or `clamp`, depending on whether the range is `min..`, + /// `..=max`, or `min..=max`, respectively. Exclusive ranges are not permitted. + /// + /// # Panics + /// + /// Panics on `min..=max` if `min > max`. + /// + /// # Examples + /// + /// ``` + /// #![feature(clamp_to)] + /// assert_eq!((-3).clamp_to(-2..=1), -2); + /// assert_eq!(0.clamp_to(-2..=1), 0); + /// assert_eq!(2.clamp_to(..=1), 1); + /// assert_eq!(5.clamp_to(7..), 7); + /// ``` + #[must_use] + #[inline] + #[unstable(feature = "clamp_to", issue = "147781")] + fn clamp_to(self, range: R) -> Self + where + Self: Sized + [const] Destruct, + R: [const] ClampBounds, + { + range.clamp(self) + } } /// Derive macro generating an impl of the trait [`Ord`]. diff --git a/library/core/src/cmp/clamp.rs b/library/core/src/cmp/clamp.rs new file mode 100644 index 0000000000000..dd496babbc659 --- /dev/null +++ b/library/core/src/cmp/clamp.rs @@ -0,0 +1,98 @@ +use crate::marker::Destruct; +use crate::ops::{RangeFrom, RangeFull, RangeInclusive, RangeToInclusive}; + +/// Trait for ranges supported by [`Ord::clamp_to`]. +#[unstable(feature = "clamp_bounds", issue = "147781")] +#[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")] +pub const trait ClampBounds: Sized { + /// The implementation of [`Ord::clamp_to`]. + fn clamp(self, value: T) -> T + where + T: [const] Destruct; +} + +#[unstable(feature = "clamp_bounds", issue = "147781")] +#[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")] +impl const ClampBounds for RangeFrom +where + T: [const] Ord, +{ + fn clamp(self, value: T) -> T + where + T: [const] Destruct, + { + value.max(self.start) + } +} + +#[unstable(feature = "clamp_bounds", issue = "147781")] +#[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")] +impl const ClampBounds for RangeToInclusive +where + T: [const] Ord, +{ + fn clamp(self, value: T) -> T + where + T: [const] Destruct, + { + value.min(self.end) + } +} + +#[unstable(feature = "clamp_bounds", issue = "147781")] +#[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")] +impl const ClampBounds for RangeInclusive +where + T: [const] Ord, +{ + fn clamp(self, value: T) -> T + where + T: [const] Destruct, + { + let (start, end) = self.into_inner(); + value.clamp(start, end) + } +} + +#[unstable(feature = "clamp_bounds", issue = "147781")] +#[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")] +impl const ClampBounds for RangeFull { + fn clamp(self, value: T) -> T { + value + } +} + +macro impl_for_float($t:ty) { + #[unstable(feature = "clamp_bounds", issue = "147781")] + #[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")] + impl const ClampBounds<$t> for RangeFrom<$t> { + fn clamp(self, value: $t) -> $t { + value.max(self.start) + } + } + + #[unstable(feature = "clamp_bounds", issue = "147781")] + #[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")] + impl const ClampBounds<$t> for RangeToInclusive<$t> { + fn clamp(self, value: $t) -> $t { + value.min(self.end) + } + } + + #[unstable(feature = "clamp_bounds", issue = "147781")] + #[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")] + impl const ClampBounds<$t> for RangeInclusive<$t> { + fn clamp(self, value: $t) -> $t { + let (start, end) = self.into_inner(); + // Deliberately avoid using `clamp` to handle NaN consistently + value.max(start).min(end) + } + } +} + +// #[unstable(feature = "f16", issue = "116909")] +impl_for_float!(f16); +impl_for_float!(f32); +impl_for_float!(f64); +// #[unstable(feature = "f128", issue = "116909")] +impl_for_float!(f128); diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index c17f55a25896a..bb542b9b160fc 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -1454,6 +1454,39 @@ impl f128 { self.clamp(-limit, limit) } + /// Restrict a value to a certain range. + /// + /// This is largely equal to `max`, `min`, or `clamp`, depending on whether the range is + /// `min..`, `..=max`, or `min..=max`, respectively. However, whereas `clamp` panics on NaN + /// values, this function treats them as unbounded, like `max` and `min`. + /// + /// Exclusive ranges are not permitted. + /// + /// # Panics + /// + /// Panics on `min..=max` if `min > max`. + /// + /// # Examples + /// + /// ``` + /// #![feature(f128, clamp_to)] + /// assert_eq!((-3.0f128).clamp_to(-2.0..=1.0), -2.0); + /// assert_eq!(0.0f128.clamp_to(-2.0..=1.0), 0.0); + /// assert_eq!(2.0f128.clamp_to(..=1.0), 1.0); + /// assert_eq!(5.0f128.clamp_to(7.0..), 7.0); + /// assert_eq!(4.0f128.clamp_to(1.0..=f128::NAN), 4.0); + /// ``` + #[must_use] + #[inline] + #[unstable(feature = "clamp_to", issue = "147781")] + pub fn clamp_to(self, range: R) -> Self + where + Self: Sized, + R: crate::cmp::ClampBounds, + { + range.clamp(self) + } + /// Computes the absolute value of `self`. /// /// This function always returns the precise result. diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 110465068b8f6..5d9d269c8c9e7 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1440,6 +1440,39 @@ impl f16 { self.clamp(-limit, limit) } + /// Restrict a value to a certain range. + /// + /// This is largely equal to `max`, `min`, or `clamp`, depending on whether the range is + /// `min..`, `..=max`, or `min..=max`, respectively. However, whereas `clamp` panics on NaN + /// values, this function treats them as unbounded, like `max` and `min`. + /// + /// Exclusive ranges are not permitted. + /// + /// # Panics + /// + /// Panics on `min..=max` if `min > max`. + /// + /// # Examples + /// + /// ``` + /// #![feature(f16, clamp_to)] + /// assert_eq!((-3.0f16).clamp_to(-2.0..=1.0), -2.0); + /// assert_eq!(0.0f16.clamp_to(-2.0..=1.0), 0.0); + /// assert_eq!(2.0f16.clamp_to(..=1.0), 1.0); + /// assert_eq!(5.0f16.clamp_to(7.0..), 7.0); + /// assert_eq!(4.0f16.clamp_to(1.0..=f16::NAN), 4.0); + /// ``` + #[must_use] + #[inline] + #[unstable(feature = "clamp_to", issue = "147781")] + pub fn clamp_to(self, range: R) -> Self + where + Self: Sized, + R: crate::cmp::ClampBounds, + { + range.clamp(self) + } + /// Computes the absolute value of `self`. /// /// This function always returns the precise result. diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index f9cb7cc650f4f..73c7acbd35ac8 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1608,6 +1608,39 @@ impl f32 { self.clamp(-limit, limit) } + /// Restrict a value to a certain range. + /// + /// This is largely equal to `max`, `min`, or `clamp`, depending on whether the range is + /// `min..`, `..=max`, or `min..=max`, respectively. However, whereas `clamp` panics on NaN + /// values, this function treats them as unbounded, like `max` and `min`. + /// + /// Exclusive ranges are not permitted. + /// + /// # Panics + /// + /// Panics on `min..=max` if `min > max`. + /// + /// # Examples + /// + /// ``` + /// #![feature(clamp_to)] + /// assert_eq!((-3.0f32).clamp_to(-2.0..=1.0), -2.0); + /// assert_eq!(0.0f32.clamp_to(-2.0..=1.0), 0.0); + /// assert_eq!(2.0f32.clamp_to(..=1.0), 1.0); + /// assert_eq!(5.0f32.clamp_to(7.0..), 7.0); + /// assert_eq!(4.0f32.clamp_to(1.0..=f32::NAN), 4.0); + /// ``` + #[must_use] + #[inline] + #[unstable(feature = "clamp_to", issue = "147781")] + pub fn clamp_to(self, range: R) -> Self + where + Self: Sized, + R: crate::cmp::ClampBounds, + { + range.clamp(self) + } + /// Computes the absolute value of `self`. /// /// This function always returns the precise result. diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 87f5505ce2b33..292e47c78b6d4 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1588,6 +1588,39 @@ impl f64 { self.clamp(-limit, limit) } + /// Restrict a value to a certain range. + /// + /// This is largely equal to `max`, `min`, or `clamp`, depending on whether the range is + /// `min..`, `..=max`, or `min..=max`, respectively. However, whereas `clamp` panics on NaN + /// values, this function treats them as unbounded, like `max` and `min`. + /// + /// Exclusive ranges are not permitted. + /// + /// # Panics + /// + /// Panics on `min..=max` if `min > max`. + /// + /// # Examples + /// + /// ``` + /// #![feature(clamp_to)] + /// assert_eq!((-3.0f64).clamp_to(-2.0..=1.0), -2.0); + /// assert_eq!(0.0f64.clamp_to(-2.0..=1.0), 0.0); + /// assert_eq!(2.0f64.clamp_to(..=1.0), 1.0); + /// assert_eq!(5.0f64.clamp_to(7.0..), 7.0); + /// assert_eq!(4.0f64.clamp_to(1.0..=f64::NAN), 4.0); + /// ``` + #[must_use] + #[inline] + #[unstable(feature = "clamp_to", issue = "147781")] + pub fn clamp_to(self, range: R) -> Self + where + Self: Sized, + R: crate::cmp::ClampBounds, + { + range.clamp(self) + } + /// Computes the absolute value of `self`. /// /// This function always returns the precise result. From 38a0099f1b3bc31653a588c7c850bb58ccf95235 Mon Sep 17 00:00:00 2001 From: Kyuuhachi Date: Thu, 18 Dec 2025 19:01:31 +0100 Subject: [PATCH 2/5] Remove trivial bounds --- library/core/src/num/f128.rs | 1 - library/core/src/num/f16.rs | 1 - library/core/src/num/f32.rs | 1 - library/core/src/num/f64.rs | 1 - 4 files changed, 4 deletions(-) diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index bb542b9b160fc..b5bf3c60f2f40 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -1481,7 +1481,6 @@ impl f128 { #[unstable(feature = "clamp_to", issue = "147781")] pub fn clamp_to(self, range: R) -> Self where - Self: Sized, R: crate::cmp::ClampBounds, { range.clamp(self) diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 5d9d269c8c9e7..41365fba8be6c 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1467,7 +1467,6 @@ impl f16 { #[unstable(feature = "clamp_to", issue = "147781")] pub fn clamp_to(self, range: R) -> Self where - Self: Sized, R: crate::cmp::ClampBounds, { range.clamp(self) diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 73c7acbd35ac8..39260d23f010b 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1635,7 +1635,6 @@ impl f32 { #[unstable(feature = "clamp_to", issue = "147781")] pub fn clamp_to(self, range: R) -> Self where - Self: Sized, R: crate::cmp::ClampBounds, { range.clamp(self) diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 292e47c78b6d4..e6f71b7478d77 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1615,7 +1615,6 @@ impl f64 { #[unstable(feature = "clamp_to", issue = "147781")] pub fn clamp_to(self, range: R) -> Self where - Self: Sized, R: crate::cmp::ClampBounds, { range.clamp(self) From f02e848d7facb4778d1368ce5c10fc9f5b80a782 Mon Sep 17 00:00:00 2001 From: Kyuuhachi Date: Thu, 18 Dec 2025 23:30:15 +0100 Subject: [PATCH 3/5] Panic on NaN --- library/core/src/cmp/clamp.rs | 5 +++-- library/core/src/num/f128.rs | 13 ++++++++----- library/core/src/num/f16.rs | 13 ++++++++----- library/core/src/num/f32.rs | 13 ++++++++----- library/core/src/num/f64.rs | 13 ++++++++----- 5 files changed, 35 insertions(+), 22 deletions(-) diff --git a/library/core/src/cmp/clamp.rs b/library/core/src/cmp/clamp.rs index dd496babbc659..e2dcecc533577 100644 --- a/library/core/src/cmp/clamp.rs +++ b/library/core/src/cmp/clamp.rs @@ -67,6 +67,7 @@ macro impl_for_float($t:ty) { #[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")] impl const ClampBounds<$t> for RangeFrom<$t> { fn clamp(self, value: $t) -> $t { + assert!(!self.start.is_nan(), "min was NaN"); value.max(self.start) } } @@ -75,6 +76,7 @@ macro impl_for_float($t:ty) { #[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")] impl const ClampBounds<$t> for RangeToInclusive<$t> { fn clamp(self, value: $t) -> $t { + assert!(!self.end.is_nan(), "max was NaN"); value.min(self.end) } } @@ -84,8 +86,7 @@ macro impl_for_float($t:ty) { impl const ClampBounds<$t> for RangeInclusive<$t> { fn clamp(self, value: $t) -> $t { let (start, end) = self.into_inner(); - // Deliberately avoid using `clamp` to handle NaN consistently - value.max(start).min(end) + value.clamp(start, end) } } } diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index b5bf3c60f2f40..8f70f94194e7c 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -1454,17 +1454,20 @@ impl f128 { self.clamp(-limit, limit) } - /// Restrict a value to a certain range. + /// Restrict a value to a certain range, unless it is NaN. /// /// This is largely equal to `max`, `min`, or `clamp`, depending on whether the range is - /// `min..`, `..=max`, or `min..=max`, respectively. However, whereas `clamp` panics on NaN - /// values, this function treats them as unbounded, like `max` and `min`. + /// `min..`, `..=max`, or `min..=max`, respectively. However, unlike `max` and `min`, it will + /// panic if any bound is NaN. + /// + /// Note that this function returns NaN if the initial value was NaN as + /// well. /// /// Exclusive ranges are not permitted. /// /// # Panics /// - /// Panics on `min..=max` if `min > max`. + /// Panics on `min..=max` if `min > max`, or if any bound is NaN. /// /// # Examples /// @@ -1474,7 +1477,7 @@ impl f128 { /// assert_eq!(0.0f128.clamp_to(-2.0..=1.0), 0.0); /// assert_eq!(2.0f128.clamp_to(..=1.0), 1.0); /// assert_eq!(5.0f128.clamp_to(7.0..), 7.0); - /// assert_eq!(4.0f128.clamp_to(1.0..=f128::NAN), 4.0); + /// assert!(f128::NAN.clamp_to(1.0..=2.0).is_nan()); /// ``` #[must_use] #[inline] diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 41365fba8be6c..4dc8072d956d0 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1440,17 +1440,20 @@ impl f16 { self.clamp(-limit, limit) } - /// Restrict a value to a certain range. + /// Restrict a value to a certain range, unless it is NaN. /// /// This is largely equal to `max`, `min`, or `clamp`, depending on whether the range is - /// `min..`, `..=max`, or `min..=max`, respectively. However, whereas `clamp` panics on NaN - /// values, this function treats them as unbounded, like `max` and `min`. + /// `min..`, `..=max`, or `min..=max`, respectively. However, unlike `max` and `min`, it will + /// panic if any bound is NaN. + /// + /// Note that this function returns NaN if the initial value was NaN as + /// well. /// /// Exclusive ranges are not permitted. /// /// # Panics /// - /// Panics on `min..=max` if `min > max`. + /// Panics on `min..=max` if `min > max`, or if any bound is NaN. /// /// # Examples /// @@ -1460,7 +1463,7 @@ impl f16 { /// assert_eq!(0.0f16.clamp_to(-2.0..=1.0), 0.0); /// assert_eq!(2.0f16.clamp_to(..=1.0), 1.0); /// assert_eq!(5.0f16.clamp_to(7.0..), 7.0); - /// assert_eq!(4.0f16.clamp_to(1.0..=f16::NAN), 4.0); + /// assert!(f16::NAN.clamp_to(1.0..=2.0).is_nan()); /// ``` #[must_use] #[inline] diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 39260d23f010b..53cc5d27bcaa4 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1608,17 +1608,20 @@ impl f32 { self.clamp(-limit, limit) } - /// Restrict a value to a certain range. + /// Restrict a value to a certain range, unless it is NaN. /// /// This is largely equal to `max`, `min`, or `clamp`, depending on whether the range is - /// `min..`, `..=max`, or `min..=max`, respectively. However, whereas `clamp` panics on NaN - /// values, this function treats them as unbounded, like `max` and `min`. + /// `min..`, `..=max`, or `min..=max`, respectively. However, unlike `max` and `min`, it will + /// panic if any bound is NaN. + /// + /// Note that this function returns NaN if the initial value was NaN as + /// well. /// /// Exclusive ranges are not permitted. /// /// # Panics /// - /// Panics on `min..=max` if `min > max`. + /// Panics on `min..=max` if `min > max`, or if any bound is NaN. /// /// # Examples /// @@ -1628,7 +1631,7 @@ impl f32 { /// assert_eq!(0.0f32.clamp_to(-2.0..=1.0), 0.0); /// assert_eq!(2.0f32.clamp_to(..=1.0), 1.0); /// assert_eq!(5.0f32.clamp_to(7.0..), 7.0); - /// assert_eq!(4.0f32.clamp_to(1.0..=f32::NAN), 4.0); + /// assert!(f32::NAN.clamp_to(1.0..=2.0).is_nan()); /// ``` #[must_use] #[inline] diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index e6f71b7478d77..4a2b7cc6184e8 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1588,17 +1588,20 @@ impl f64 { self.clamp(-limit, limit) } - /// Restrict a value to a certain range. + /// Restrict a value to a certain range, unless it is NaN. /// /// This is largely equal to `max`, `min`, or `clamp`, depending on whether the range is - /// `min..`, `..=max`, or `min..=max`, respectively. However, whereas `clamp` panics on NaN - /// values, this function treats them as unbounded, like `max` and `min`. + /// `min..`, `..=max`, or `min..=max`, respectively. However, unlike `max` and `min`, it will + /// panic if any bound is NaN. + /// + /// Note that this function returns NaN if the initial value was NaN as + /// well. /// /// Exclusive ranges are not permitted. /// /// # Panics /// - /// Panics on `min..=max` if `min > max`. + /// Panics on `min..=max` if `min > max`, or if any bound is NaN. /// /// # Examples /// @@ -1608,7 +1611,7 @@ impl f64 { /// assert_eq!(0.0f64.clamp_to(-2.0..=1.0), 0.0); /// assert_eq!(2.0f64.clamp_to(..=1.0), 1.0); /// assert_eq!(5.0f64.clamp_to(7.0..), 7.0); - /// assert_eq!(4.0f64.clamp_to(1.0..=f64::NAN), 4.0); + /// assert!(f64::NAN.clamp_to(1.0..=2.0).is_nan()); /// ``` #[must_use] #[inline] From 4d3f68d35708f0c99f7f0763cd3237c6ca16cf29 Mon Sep 17 00:00:00 2001 From: Kyuuhachi Date: Tue, 12 May 2026 22:34:46 +0200 Subject: [PATCH 4/5] Make assert messages consistent with field names --- library/core/src/cmp/clamp.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/core/src/cmp/clamp.rs b/library/core/src/cmp/clamp.rs index e2dcecc533577..d6a67c22e6cee 100644 --- a/library/core/src/cmp/clamp.rs +++ b/library/core/src/cmp/clamp.rs @@ -67,7 +67,7 @@ macro impl_for_float($t:ty) { #[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")] impl const ClampBounds<$t> for RangeFrom<$t> { fn clamp(self, value: $t) -> $t { - assert!(!self.start.is_nan(), "min was NaN"); + assert!(!self.start.is_nan(), "start was NaN"); value.max(self.start) } } @@ -76,7 +76,7 @@ macro impl_for_float($t:ty) { #[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")] impl const ClampBounds<$t> for RangeToInclusive<$t> { fn clamp(self, value: $t) -> $t { - assert!(!self.end.is_nan(), "max was NaN"); + assert!(!self.end.is_nan(), "end was NaN"); value.min(self.end) } } @@ -86,6 +86,7 @@ macro impl_for_float($t:ty) { impl const ClampBounds<$t> for RangeInclusive<$t> { fn clamp(self, value: $t) -> $t { let (start, end) = self.into_inner(); + assert!(start <= end, "start > end, or either was NaN"); value.clamp(start, end) } } From 8786b0d05c5da12ce27cfd03956b6e09c221cf40 Mon Sep 17 00:00:00 2001 From: Kyuuhachi Date: Tue, 12 May 2026 23:10:47 +0200 Subject: [PATCH 5/5] Add clamp_to coretests --- library/coretests/tests/lib.rs | 1 + library/coretests/tests/num/floats.rs | 42 +++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 12b81fea9d27c..992b7697f2b49 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -13,6 +13,7 @@ #![feature(bstr)] #![feature(cfg_target_has_reliable_f16_f128)] #![feature(char_internals)] +#![feature(clamp_to)] #![feature(clone_to_uninit)] #![feature(cmp_minmax)] #![feature(const_array)] diff --git a/library/coretests/tests/num/floats.rs b/library/coretests/tests/num/floats.rs index 1d7956b41c9d1..e20540091da0c 100644 --- a/library/coretests/tests/num/floats.rs +++ b/library/coretests/tests/num/floats.rs @@ -1359,6 +1359,48 @@ float_test! { } } +float_test! { + name: clamp_to_min_greater_than_max, + attrs: { + const: #[cfg(false)], + f16: #[should_panic, cfg(target_has_reliable_f16)], + f32: #[should_panic], + f64: #[should_panic], + f128: #[should_panic, cfg(target_has_reliable_f128)], + }, + test { + let _ = Float::ONE.clamp_to(3.0..=1.0); + } +} + +float_test! { + name: clamp_to_min_is_nan, + attrs: { + const: #[cfg(false)], + f16: #[should_panic, cfg(target_has_reliable_f16)], + f32: #[should_panic], + f64: #[should_panic], + f128: #[should_panic, cfg(target_has_reliable_f128)], + }, + test { + let _ = Float::ONE.clamp_to(Float::NAN..=1.0); + } +} + +float_test! { + name: clamp_to_max_is_nan, + attrs: { + const: #[cfg(false)], + f16: #[should_panic, cfg(target_has_reliable_f16)], + f32: #[should_panic], + f64: #[should_panic], + f128: #[should_panic, cfg(target_has_reliable_f128)], + }, + test { + let _ = Float::ONE.clamp_to(3.0..=Float::NAN); + } +} + float_test! { name: total_cmp, attrs: {