about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/core/src/num/nonzero.rs33
1 files changed, 33 insertions, 0 deletions
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 7d60686597a..bda691b16d4 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -171,6 +171,39 @@ macro_rules! nonzero_integer {
                 }
             }
 
+            /// Converts a primitive mutable reference to a non-zero mutable reference
+            /// without checking whether the referenced value is non-zero.
+            /// This results in undefined behavior if `*n` is zero.
+            ///
+            /// # Safety
+            /// The referenced value must not be currently zero.
+            #[unstable(feature = "nonzero_from_mut", issue = "106290")]
+            #[must_use]
+            #[inline]
+            pub unsafe fn from_mut_unchecked(n: &mut $Int) -> &mut Self {
+                // SAFETY: Self is repr(transparent), and the value is assumed to be non-zero.
+                unsafe {
+                    let n_alias = &mut *n;
+                    core::intrinsics::assert_unsafe_precondition!(
+                        concat!(stringify!($Ty), "::from_mut_unchecked requires the argument to dereference as non-zero"),
+                        (n_alias: &mut $Int) => *n_alias != 0
+                    );
+                    &mut *(n as *mut $Int as *mut Self)
+                }
+            }
+
+            /// Converts a primitive mutable reference to a non-zero mutable reference
+            /// if the referenced integer is not zero.
+            #[unstable(feature = "nonzero_from_mut", issue = "106290")]
+            #[must_use]
+            #[inline]
+            pub fn from_mut(n: &mut $Int) -> Option<&mut Self> {
+                // SAFETY: Self is repr(transparent), and the value is non-zero.
+                // As long as the returned reference is alive,
+                // the user cannot `*n = 0` directly.
+                (*n != 0).then(|| unsafe { &mut *(n as *mut $Int as *mut Self) })
+            }
+
             /// Returns the value as a primitive type.
             #[$stability]
             #[inline]