Skip to content

Commit da4a8dd

Browse files
branpkmbrubeck
authored andcommitted
Make assignment operators panic safe
1 parent 96672a8 commit da4a8dd

File tree

2 files changed

+20
-10
lines changed

2 files changed

+20
-10
lines changed

src/lib.rs

+5-10
Original file line numberDiff line numberDiff line change
@@ -356,8 +356,7 @@ impl<T: Float + AddAssign> AddAssign for NotNan<T> {
356356
/// Panics if the provided value is NaN.
357357
impl<T: Float + AddAssign> AddAssign<T> for NotNan<T> {
358358
fn add_assign(&mut self, other: T) {
359-
self.0 += other;
360-
assert!(!self.0.is_nan(), "Addition resulted in NaN");
359+
*self = *self + other;
361360
}
362361
}
363362

@@ -404,8 +403,7 @@ impl<T: Float + SubAssign> SubAssign for NotNan<T> {
404403
/// Panics if the provided value is NaN or the computation results in NaN
405404
impl<T: Float + SubAssign> SubAssign<T> for NotNan<T> {
406405
fn sub_assign(&mut self, other: T) {
407-
self.0 -= other;
408-
assert!(!self.0.is_nan(), "Subtraction resulted in NaN");
406+
*self = *self - other;
409407
}
410408
}
411409

@@ -439,8 +437,7 @@ impl<T: Float + MulAssign> MulAssign for NotNan<T> {
439437
/// Panics if the provided value is NaN.
440438
impl<T: Float + MulAssign> MulAssign<T> for NotNan<T> {
441439
fn mul_assign(&mut self, other: T) {
442-
self.0 *= other;
443-
assert!(!self.0.is_nan(), "Multiplication resulted in NaN");
440+
*self = *self * other;
444441
}
445442
}
446443

@@ -486,8 +483,7 @@ impl<T: Float + DivAssign> DivAssign for NotNan<T> {
486483
/// Panics if the provided value is NaN or the computation results in NaN
487484
impl<T: Float + DivAssign> DivAssign<T> for NotNan<T> {
488485
fn div_assign(&mut self, other: T) {
489-
self.0 /= other;
490-
assert!(!self.0.is_nan(), "Division resulted in NaN");
486+
*self = *self / other;
491487
}
492488
}
493489

@@ -521,8 +517,7 @@ impl<T: Float + RemAssign> RemAssign for NotNan<T> {
521517
/// Panics if the provided value is NaN or the computation results in NaN
522518
impl<T: Float + RemAssign> RemAssign<T> for NotNan<T> {
523519
fn rem_assign(&mut self, other: T) {
524-
self.0 %= other;
525-
assert!(!self.0.is_nan(), "Rem resulted in NaN");
520+
*self = *self % other;
526521
}
527522
}
528523

tests/test.rs

+15
Original file line numberDiff line numberDiff line change
@@ -579,3 +579,18 @@ fn not_nan64_sum_product() {
579579
assert_eq!([a,b,c].iter().product::<NotNan<_>>(), a * b * c);
580580

581581
}
582+
583+
#[test]
584+
fn not_nan_panic_safety() {
585+
let catch_op = |mut num, op: fn(&mut NotNan<_>)| {
586+
let mut num_ref = panic::AssertUnwindSafe(&mut num);
587+
let _ = panic::catch_unwind(move || op(*num_ref));
588+
num
589+
};
590+
591+
assert!(!catch_op(NotNan::from(f32::INFINITY), |a| *a += f32::NEG_INFINITY).is_nan());
592+
assert!(!catch_op(NotNan::from(f32::INFINITY), |a| *a -= f32::INFINITY).is_nan());
593+
assert!(!catch_op(NotNan::from(0.0), |a| *a *= f32::INFINITY).is_nan());
594+
assert!(!catch_op(NotNan::from(0.0), |a| *a /= 0.0).is_nan());
595+
assert!(!catch_op(NotNan::from(0.0), |a| *a %= 0.0).is_nan());
596+
}

0 commit comments

Comments
 (0)